1/* ****************************************************************************
    2    DATE/TIME UTILITIES
    3
    4 Extensions to teh built-in date/time utilities, to allow for timezone handling and formatting.
    5    https://www.swi-prolog.org/pldoc/man?section=timedate
    6    *************************************************************************** */
    7:- module(datetime_ssardina,
    8    [
    9        get_date_time/1,
   10        get_date_time_tz/2,
   11        iso_timestamp_string_atom/2,
   12        get_iso_timestamp/1,
   13        get_iso_timestamp/2,
   14        stamp_date_time/2,
   15        stamp_date_time_tz/3,
   16        weekday_number/2
   17    ]).   18
   19:- use_module(facts/timezones).  % Facts about timezones
 get_date_time(-DateTime) is det
Retrieves the current date and time as a date-time structure in the local timezone.
   24get_date_time(DT) :-
   25	get_time(T),
   26	stamp_date_time(T, DT).
 get_date_time_tz(-DateTime, +Timezone) is det
Retrieves the current date and time as a date-time structure. If a timezone is specified, it adjusts the date-time accordingly.
   33get_date_time_tz(DT, TZ) :-
   34    get_time(T),
   35    stamp_date_time_tz(T, DT, TZ).
 stamp_date_time(+Stamp, -DateTime) is det
Generalization of stamp-date_time/3 to default local timezone https://www.swi-prolog.org/pldoc/doc_for?object=stamp_date_time/3
   42stamp_date_time(T, DT) :-
   43	stamp_date_time_tz(T, DT, local).
 stamp_date_time_tz(+Stamp, -DateTime, +Timezone) is det
Converts a timestamp to a date-time structure, taking into account the specified timezone as IANA identifiers (e.g., "America/New_York").

If the timezone is not recognized, it falls back to using the default Offset timezone

   52stamp_date_time_tz(T, DT, TZ) :-
   53    timezone(TZ, Offset), !,
   54    stamp_date_time(T, DT, Offset).
   55stamp_date_time_tz(T, DT, TZ) :-
   56	stamp_date_time(T, DT, TZ).
 iso_timestamp(+DTISOStr:str, -DTISOAtom:atom)
Convert a timestamp string (e.g. "1995-01-23 09:00:00") into an ISO 8601 format atom (e.g. '1995-01-23T09:00:00') for Prolog facts.

It accepts both ISO format (with 'T') and space-separated format, but always returns an ISO atom.

SWIPL Doc on time: https://www.swi-prolog.org/pldoc/man?section=timedate

2 ?- iso_timestamp_string_atom("1995-01-23T16:30:00", X). X = '1995-01-23T16:30:00'.

3 ?- iso_timestamp_string_atom("1995-01-23 16:30:00", X). X = '1995-01-23T16:30:00'.

   73iso_timestamp_string_atom(DTISOStr, DTISOAtom) :-
   74    parse_time(DTISOStr, _),            % with T separator already: "1995-01-23T16:30:00"
   75    atomic_list_concat([_Date, _Time], 'T', DTISOStr), !,
   76    atom_string(DTISOAtom, DTISOStr).
   77iso_timestamp_string_atom(DTISOStr, DTISOStrISO) :-
   78    atom_string(DTISOStr, DTISOStrStr), % handles "1995-01-23 16:30:00"
   79    split_string(DTISOStrStr, " ", "", [DatePart, TimePart]),
   80    atomic_list_concat([DatePart, TimePart], 'T', DTISOStrISO).
 get_iso_timestamp(-Stamp) is det
get_iso_timestamp(-Stamp, +TimeZone) is det.

Retrieves the current timestamp as an ISO 8601 formatted string in the timezone. If no timezone is specified, it defaults to the local timezone. If TimeZone is none or none(TZ), it returns the ISO timestamp without timezone information.

uses format_time/3 - https://www.swi-prolog.org/pldoc/man?predicate=format_time/3

   91get_iso_timestamp(Stamp) :-
   92    get_iso_timestamp(Stamp, local).
   93get_iso_timestamp(ISO, none) :- !,
   94    get_iso_timestamp(ISO, none(local)).
   95get_iso_timestamp(ISO, none(TZ)) :- !,
   96    get_time(Stamp),
   97    stamp_date_time_tz(Stamp, DateTime, TZ),
   98    format_time(atom(ISO), '%FT%T', DateTime).
   99get_iso_timestamp(ISO, TZ) :-
  100    get_time(Stamp),
  101    stamp_date_time_tz(Stamp, DateTime, TZ),
  102    format_time(atom(ISO), '%FT%T%:z', DateTime).
 weekday_number(+StartISO, -DayNo)
Given a timestamp string, determine the day of the week as a number (1=Monday, ..., 7=Sunday).
  109weekday_number(StartISO, DayNo) :-
  110	parse_time(StartISO, StartStamp),
  111	stamp_date_time(StartStamp, Date, local),
  112	date_time_value(date, Date, Day),
  113	day_of_the_week(Day, DayNo)