date_time¶
In [ ]:
open rust.rust_operators
open sm'_operators
In [ ]:
//// test
open testing
date_time¶
timestamp¶
In [ ]:
nominal timestamp = i64
timestamp_guid¶
In [ ]:
type timestamp_guid = guid.guid
date_time_guid¶
In [ ]:
type date_time_guid = guid.guid
In [ ]:
//// test
inl test_guid () =
guid.new_guid "FEDCBA98-7654-3210-FEDC-BA9876543210"
fsharp¶
date_time¶
In [ ]:
nominal date_time_python =
`(
backend_switch {
Python = fun () =>
global "import datetime"
}
$'' : $'datetime.datetime'
)
type date_time_switch =
{
Fsharp : $'System.DateTime'
Python : date_time_python
}
nominal date_time = $'backend_switch `(date_time_switch)'
date_time_milliseconds¶
In [ ]:
inl date_time_milliseconds
(year : int) (month : int) (day : int) (hour : int) (minute : int) (second : int) (millisecond : int)
: date_time
=
backend_switch {
Fsharp = fun () =>
$'System.DateTime (!year, !month, !day, !hour, !minute, !second, !millisecond)' : date_time
Python = fun () =>
$'datetime.datetime(!year, !month, !day, !hour, !minute, !second, !millisecond)' : date_time
}
date_time_utc¶
In [ ]:
inl date_time_utc
(year : int) (month : int) (day : int) (hour : int) (minute : int) (second : int)
: date_time
=
backend_switch {
Fsharp = fun () =>
$'System.DateTime (!year, !month, !day, !hour, !minute, !second, System.DateTimeKind.Utc)' : date_time
Python = fun () =>
$'datetime.datetime(!year, !month, !day, !hour, !minute, !second, tzinfo=datetime.timezone.utc)' : date_time
}
ticks¶
In [ ]:
inl ticks (date_time : date_time) : timestamp =
backend_switch {
Fsharp = fun () => date_time |> $'_.Ticks' : timestamp
Python = fun () => $'!date_time.timestamp()' : timestamp
}
format¶
In [ ]:
inl format (format : string) (date_time : date_time) : string =
backend_switch {
Fsharp = fun () => $'!date_time.ToString' format : string
Python = fun () => $'!date_time.strftime(!format)' : string
}
format_iso8601¶
In [ ]:
inl format_iso8601 (date_time : date_time) : string =
backend_switch {
Fsharp = fun () => date_time |> format "yyyy-MM-ddTHH-mm-ss.fff" : string
Python = fun () => date_time |> format "%Y-%m-%dT%H-%M-%S.%f" : string
}
min_value¶
In [ ]:
inl min_value () : date_time =
backend_switch {
Fsharp = fun () => $'System.DateTime.MinValue' : date_time
Python = fun () => $'datetime.datetime.min' : date_time
}
max_value¶
In [ ]:
inl max_value () : date_time =
backend_switch {
Fsharp = fun () => $'System.DateTime.MaxValue' : date_time
Python = fun () => $'datetime.datetime.max' : date_time
}
unix_epoch¶
In [ ]:
inl unix_epoch () : date_time =
backend_switch {
Fsharp = fun () => $'System.DateTime.UnixEpoch' : date_time
Python = fun () => $'datetime.datetime(1970, 1, 1)' : date_time
}
to_universal_time¶
In [ ]:
inl to_universal_time (date_time : date_time) : date_time =
backend_switch {
Fsharp = fun () => date_time |> $'_.ToUniversalTime()' : date_time
Python = fun () => $'!date_time.astimezone(datetime.timezone.utc)' : date_time
}
date_time_kind¶
In [ ]:
union date_time_kind =
| Unspecified
| Utc
| Local
specify_date_kind¶
In [ ]:
inl specify_date_kind (kind : date_time_kind) (date_time : date_time) : date_time =
inl kind : $'System.DateTimeKind' =
match kind with
| Unspecified => $'System.DateTimeKind.Unspecified'
| Utc => $'System.DateTimeKind.Utc'
| Local => $'System.DateTimeKind.Local'
$'System.DateTime.SpecifyKind (!date_time, !kind)'
time_span¶
In [ ]:
nominal time_span = $"backend_switch `({ Fsharp : $"System.TimeSpan"; Python : $"datetime.timedelta" })"
inl time_span x : time_span =
backend_switch {
Fsharp = fun () => x |> $'`time_span ' : time_span
Python = fun () => $'datetime.timedelta(!x)' : time_span
}
new_time_span¶
In [ ]:
inl new_time_span (a : date_time) (b : date_time) : time_span =
$'!b - !a '
time_span_format¶
In [ ]:
inl time_span_format (format : string) (time_span : time_span) : string =
run_target function
| (TypeScript _ | Python _) => fun () =>
$'!time_span.ToString ("c", System.Globalization.CultureInfo.InvariantCulture)'
| _ => fun () =>
$'!time_span.ToString !format '
hours¶
In [ ]:
inl hours (time_span : time_span) : i32 =
backend_switch {
Fsharp = fun () => time_span |> $'_.Hours' : i32
Python = fun () => $'!time_span.days * 24 + !time_span.seconds // 3600' : i32
}
milliseconds¶
In [ ]:
inl milliseconds (time_span : time_span) : i32 =
backend_switch {
Fsharp = fun () => time_span |> $'_.Milliseconds' : i32
Python = fun () => $'!time_span.microseconds // 1000' : i32
}
minutes¶
In [ ]:
inl minutes (time_span : time_span) : i32 =
backend_switch {
Fsharp = fun () => time_span |> $'_.Minutes' : i32
Python = fun () => $'!time_span.seconds // 60' : i32
}
seconds¶
In [ ]:
inl seconds (time_span : time_span) : i32 =
backend_switch {
Fsharp = fun () => time_span |> $'_.Seconds' : i32
Python = fun () => $'!time_span.seconds % 60' : i32
}
total_seconds¶
In [ ]:
inl total_seconds (time_span : time_span) : f64 =
backend_switch {
Fsharp = fun () => time_span |> $'_.TotalSeconds' : f64
Python = fun () => $'!time_span.total_seconds()' : f64
}
time_zone_info¶
In [ ]:
nominal time_zone_info = $'System.TimeZoneInfo'
add_days¶
In [ ]:
inl add_days (days : i32) (date_time : date_time) : date_time =
$'!date_time.AddDays' days
now¶
In [ ]:
inl now () : date_time =
backend_switch {
Fsharp = fun () => $'System.DateTime.Now' : date_time
Python = fun () =>
backend_switch {
Python = fun () =>
global "import datetime"
}
$'datetime.datetime.now()' : date_time
}
utc_now¶
In [ ]:
inl utc_now () : date_time =
backend_switch {
Fsharp = fun () => $'System.DateTime.UtcNow' : date_time
Python = fun () =>
backend_switch {
Python = fun () =>
global "import datetime"
}
$'datetime.datetime.utcnow()' : date_time
}
stopwatch¶
In [ ]:
nominal stopwatch_python =
`(
global "import timeit"
$'' : $'timeit.default_timer'
)
type stopwatch_switch =
{
Fsharp : $'System.Diagnostics.Stopwatch'
Python : stopwatch_python
}
nominal stopwatch = $'backend_switch `(stopwatch_switch)'
inl stopwatch () : stopwatch =
backend_switch {
Fsharp = fun () => $'`stopwatch ' () : stopwatch
Python = fun () => $'`stopwatch ' : stopwatch
}
In [ ]:
inl stopwatch_elapsed_milliseconds (stopwatch : stopwatch) : i64 =
$'!stopwatch.ElapsedMilliseconds'
In [ ]:
inl stopwatch_start (stopwatch : stopwatch) : () =
$'!stopwatch.Start' ()
rust¶
duration¶
In [ ]:
nominal duration =
`(
global "#if FABLE_COMPILER\n[<Fable.Core.Erase; Fable.Core.Emit(\"std::time::Duration\")>]\n#endif\ntype std_time_Duration = class end"
$'' : $'std_time_Duration'
)
date_time'¶
In [ ]:
nominal date_time' t =
`(
global "#if FABLE_COMPILER\n[<Fable.Core.Erase; Fable.Core.Emit(\"chrono::DateTime<$0>\")>]\n#endif\ntype chrono_DateTime<'T> = class end"
$'' : $'chrono_DateTime<`t>'
)
local¶
In [ ]:
nominal local =
`(
global "#if FABLE_COMPILER\n[<Fable.Core.Erase; Fable.Core.Emit(\"chrono::Local\")>]\n#endif\ntype chrono_Local = class end"
$'' : $'chrono_Local'
)
naive_date_time¶
In [ ]:
nominal naive_date_time =
`(
global "#if FABLE_COMPILER\n[<Fable.Core.Erase; Fable.Core.Emit(\"chrono::NaiveDateTime\")>]\n#endif\ntype chrono_NaiveDateTime = class end"
$'' : $'chrono_NaiveDateTime'
)
utc¶
In [ ]:
nominal utc =
`(
global "#if FABLE_COMPILER\n[<Fable.Core.Erase; Fable.Core.Emit(\"chrono::Utc\")>]\n#endif\ntype chrono_Utc = class end"
$'' : $'chrono_Utc'
)
naive_utc¶
In [ ]:
inl naive_utc (date_time : date_time' utc) : naive_date_time =
!\\(date_time, $'"$0.naive_utc()"')
to_local¶
In [ ]:
inl to_local (date_time : date_time' utc) : date_time' local =
inl naive_date_time = date_time |> naive_utc
!\\(naive_date_time, $'"chrono::offset::TimeZone::from_utc_datetime(&chrono::Local, &$0)"')
from_timestamp_micros¶
In [ ]:
inl from_timestamp_micros forall t {number; int}. (timestamp : t) : option (date_time' utc) =
inl result : optionm'.option' (date_time' utc) =
!\\(timestamp, $'"chrono::DateTime::from_timestamp_micros($0)"')
result |> optionm'.unbox
format'¶
In [ ]:
inl format' (format : string) (date_time : date_time' utc) : sm'.std_string =
!\\((date_time, #format), $'"$0.format($1).to_string()"')
format''¶
In [ ]:
inl format'' (format : string) (date_time : date_time' _) : sm'.std_string =
!\\((date_time, #format), $'"$0.format($1).to_string()"')
format_timestamp¶
In [ ]:
inl format_timestamp forall t {number; int}. (timestamp : t) =
inl timestamp = join timestamp
(timestamp / 1000)
|> from_timestamp_micros
|> optionm.map fun x =>
x
|> to_local
|> format'' "%Y-%m-%d %H:%M:%S"
|> sm'.from_std_string
|> resultm.from_option
duration_from_millis¶
In [ ]:
inl duration_from_millis (ms : u64) : duration =
inl ms = join ms
!\($'"std::time::Duration::from_millis(!ms)"')
date_time¶
time_zone_local¶
In [ ]:
inl time_zone_local () : time_zone_info =
run_target function
| Rust (Native) => fun () =>
open rust.rust_operators
!\($'"0i64.into()"')
| Fsharp _ => fun () =>
$'System.TimeZoneInfo.Local'
| _ => fun () => null ()
get_utc_offset¶
In [ ]:
inl get_utc_offset (time_zone_info : time_zone_info) (date_time : date_time) : time_span =
run_target function
| Rust _ => fun () => time_span ()
| Fsharp _ => fun () => date_time |> $'_.GetUtcOffset' (time_zone_local ())
| target => fun () => failwith $'$"date_time.get_utc_offset / target: {!target}"'
date_time_guid_from_date_time¶
In [ ]:
let date_time_guid_from_date_time (guid : guid.guid) (date_time : date_time) =
inl create prefix time_zone : date_time_guid =
inl guid = guid |> sm'.obj_to_string
$'`date_time_guid $"{!prefix}{!time_zone}{!guid.[!prefix.Length + !time_zone.Length..]}"'
run_target function
| Rust (Contract) => fun () => null ()
| Rust (Native | Wasm) => fun () =>
inl epoch =
date_time_utc 1970 1 1 0 0 0
|> to_universal_time
inl date_time =
date_time
|> specify_date_kind Local
|> to_universal_time
inl unixticks =
match date_time |> ticks, epoch |> ticks with
| timestamp date_time, timestamp epoch => date_time - epoch
inl prefix =
unixticks / 10
|> from_timestamp_micros
|> optionm.map (
to_local
>> format'' "%Y%m%d-%H%M-%S%f"
>> sm'.from_std_string
>> fun s => $'$"{!s.[0..17]}-{!s.[18..21]}-{!s.[22]}"'
)
|> optionm'.default_value ""
inl time_zone = date_time |> get_utc_offset (time_zone_local ())
inl time_zone_signal = if hours time_zone > 0 then 1u8 else 0
inl time_zone_value = time_zone |> time_span_format (join "hh:mm")
inl time_zone = $'$"{!time_zone_signal}{!time_zone_value.[0..1]}{!time_zone_value.[3..4]}"' : string
create prefix time_zone
| target => fun () =>
inl prefix = date_time |> format (join "yyyyMMdd-HHmm-ssff-ffff-f")
inl time_zone = date_time |> get_utc_offset (time_zone_local ())
inl time_zone_signal = if hours time_zone > 0 then 1u8 else 0
inl time_zone_value = time_zone |> time_span_format (join "hhmm")
inl time_zone = $'$"{!time_zone_signal}{!time_zone_value}"' : string
create prefix time_zone
In [ ]:
//// test
now () |> to_universal_time |> date_time_guid_from_date_time (test_guid ()) |> sm'.obj_to_string
|> console.write_line
20241106-0710-5645-4586-400000543210
In [ ]:
//// test
///! rust -d chrono
inl suffix = test_guid () |> sm'.obj_to_string |> sm'.range (am'.End fun x => x - 6i32) (am'.End id)
now ()
|> to_universal_time
|> date_time_guid_from_date_time (test_guid ())
|> sm'.obj_to_string
|> fun s => s |> _assert_eq' $'$"{!s.[0..29]}{!suffix}"'
__assert_eq' / actual: "20241106-0711-0445-6682-000000543210" / expected: "20241106-0711-0445-6682-000000543210"
In [ ]:
//// test
///! fsharp
///! rust -d chrono
inl suffix = test_guid () |> sm'.obj_to_string |> sm'.range (am'.End fun x => x - 6i32) (am'.End id)
min_value ()
|> specify_date_kind Local
|> date_time_guid_from_date_time (test_guid ())
|> sm'.obj_to_string
|> fun s => s |> _assert_eq' $'$"00010101-0000-0000-0000-0{!s.[25..29]}{!suffix}"'
.rs output (rust -d chrono): __assert_eq' / actual: "00010101-0000-0000-0000-000000543210" / expected: "00010101-0000-0000-0000-000000543210"
.fsx output: __assert_eq' / actual: "00010101-0000-0000-0000-000000543210" / expected: "00010101-0000-0000-0000-000000543210"
In [ ]:
//// test
///! fsharp
inl suffix = test_guid () |> sm'.obj_to_string |> sm'.range (am'.End fun x => x - 6i32) (am'.End id)
max_value ()
|> specify_date_kind Utc
|> add_days -1
|> date_time_guid_from_date_time (test_guid ())
|> sm'.obj_to_string
|> fun s => s |> _assert_eq $'$"99991230-2359-5999-9999-9{!s.[25..29]}{!suffix}"'
__assert_eq / actual: "99991230-2359-5999-9999-900000543210" / expected: "99991230-2359-5999-9999-900000543210"
In [ ]:
//// test
///! rust -d chrono
inl suffix = test_guid () |> sm'.obj_to_string |> sm'.range (am'.End fun x => x - 6i32) (am'.End id)
max_value ()
|> specify_date_kind Utc
|> add_days -1
|> date_time_guid_from_date_time (test_guid ())
|> sm'.obj_to_string
|> fun s => s |> _assert_eq $'$"99991230-2359-5999-9999-0{!s.[25..29]}{!suffix}"'
__assert_eq / actual: "99991230-2359-5999-9999-000000543210" / expected: "99991230-2359-5999-9999-000000543210"
In [ ]:
//// test
inl suffix = test_guid () |> sm'.obj_to_string |> sm'.range (am'.End fun x => x - 6i32) (am'.End id)
unix_epoch ()
|> specify_date_kind Utc
|> add_days 1
|> date_time_guid_from_date_time (test_guid ())
|> sm'.obj_to_string
|> fun s => s |> _assert_eq $'$"19700102-0000-0000-0000-0{!s.[25..29]}{!suffix}"'
__assert_eq / actual: "19700102-0000-0000-0000-000000543210" / expected: "19700102-0000-0000-0000-000000543210"
In [ ]:
//// test
///! rust -d chrono
inl suffix = test_guid () |> sm'.obj_to_string |> sm'.range (am'.End fun x => x - 6i32) (am'.End id)
unix_epoch ()
|> specify_date_kind Utc
|> add_days 1
|> date_time_guid_from_date_time (test_guid ())
|> sm'.obj_to_string
|> fun s => s |> _assert_eq $'$"19700102-0000-0000-0000-0{!s.[25..29]}{!suffix}"'
__assert_eq / actual: "19700102-0000-0000-0000-000000543210" / expected: "19700102-0000-0000-0000-000000543210"
date_time_from_guid¶
In [ ]:
inl date_time_from_guid (date_time_guid : date_time_guid) =
inl date_time_guid = date_time_guid |> sm'.obj_to_string
inl sm_replace = sm'.replace "-" ""
run_target_args (fun () => sm_replace) function
| (Rust _ | TypeScript _) => fun sm_replace =>
$'System.DateTime.Parse (!date_time_guid.[..24] |> !sm_replace)' : date_time
| _ => fun sm_replace => $'System.DateTime.ParseExact (!date_time_guid.[..24] |> !sm_replace, "yyyyMMddHHmmssfffffff", null)' : date_time
In [ ]:
//// test
date_time_from_guid (guid.new_guid "00010101-0000-0000-0000-0a9876543210")
|> _assert_eq' (min_value ())
__assert_eq' / actual: 01/01/0001 00:00:00 / expected: 01/01/0001 00:00:00
In [ ]:
//// test
date_time_from_guid (guid.new_guid $'$"99991231-2359-5999-9999-9{(!test_guid () |> string).[^10..]}"')
|> _assert_eq' (max_value ())
__assert_eq' / actual: 12/31/9999 23:59:59 / expected: 12/31/9999 23:59:59
In [ ]:
//// test
date_time_from_guid (guid.new_guid $'$"19700101-0000-0000-0000-0{(!test_guid () |> string).[^10..]}"')
|> _assert_eq' $'System.DateTime.UnixEpoch'
__assert_eq' / actual: 01/01/1970 00:00:00 / expected: 01/01/1970 00:00:00
timestamp_guid_from_timestamp¶
In [ ]:
inl timestamp_guid_from_timestamp (guid : guid.guid) (timestamp : timestamp) : timestamp_guid =
inl guid = guid |> sm'.obj_to_string
inl timestamp = timestamp |> sm'.obj_to_string |> sm'.pad_left 18i32 '0'
$'`timestamp_guid $"{!timestamp.[0..7]}-{!timestamp.[8..11]}-{!timestamp.[12..15]}-{!timestamp.[16..17]}{!guid.[21..]}"'
In [ ]:
//// test
timestamp_guid_from_timestamp (test_guid ()) (timestamp 0i64)
|> _assert_eq' (guid.new_guid "00000000-0000-0000-00dc-ba9876543210")
__assert_eq' / actual: 00000000-0000-0000-00dc-ba9876543210 / expected: 00000000-0000-0000-00dc-ba9876543210
In [ ]:
//// test
timestamp_guid_from_timestamp (test_guid ()) (timestamp 999999999999999999i64)
|> _assert_eq' (guid.new_guid $'$"99999999-9999-9999-99dc-b{(!test_guid () |> string).[^10..]}"')
__assert_eq' / actual: 99999999-9999-9999-99dc-ba9876543210 / expected: 99999999-9999-9999-99dc-ba9876543210
timestamp_from_guid¶
In [ ]:
inl timestamp_from_guid (guid : date_time_guid) : timestamp =
inl guid = guid |> sm'.obj_to_string
$'`i64 $"{!guid.[0..7]}{!guid.[9..12]}{!guid.[14..17]}{!guid.[19..20]}"'
In [ ]:
//// test
timestamp_from_guid (guid.new_guid "00000000-0000-0000-00dc-ba9876543210")
|> _assert_eq (timestamp 0)
__assert_eq / actual: 0L / expected: 0L
In [ ]:
//// test
timestamp_from_guid (guid.new_guid $'$"99999999-9999-9999-99{(!test_guid () |> string).[^14..]}"')
|> _assert_eq (timestamp 999999999999999999)
__assert_eq / actual: 999999999999999999L / expected: 999999999999999999L
new_guid_from_date_time¶
In [ ]:
inl new_guid_from_date_time (date_time : date_time) =
inl guid = guid.new_raw_guid ()
date_time_guid_from_date_time guid date_time
In [ ]:
//// test
utc_now ()
|> new_guid_from_date_time
|> date_time_from_guid
|> fun date_time => new_time_span date_time (utc_now ()) |> total_seconds |> i32
|> _assert_eq 0
__assert_eq / actual: 0 / expected: 0
new_guid_from_timestamp¶
In [ ]:
inl new_guid_from_timestamp (timestamp : timestamp) =
inl guid = guid.new_raw_guid ()
timestamp_guid_from_timestamp guid timestamp
In [ ]:
//// test
utc_now ()
|> ticks
|> new_guid_from_timestamp
|> timestamp_from_guid
|> fun (timestamp timestamp) => (timestamp - (utc_now () |> ticks |> fun (timestamp x) => x)) / 100000i64
|> _assert_eq 0i64
__assert_eq / actual: 0L / expected: 0L
main¶
In [ ]:
inl main () =
$'let date_time_guid_from_date_time x = !date_time_guid_from_date_time x' : ()
$'let date_time_from_guid x = !date_time_from_guid x' : ()
$'let timestamp_guid_from_timestamp x = !timestamp_guid_from_timestamp x' : ()
$'let timestamp_from_guid x = !timestamp_from_guid x' : ()
$'let new_guid_from_date_time x = !new_guid_from_date_time x' : ()
$'let new_guid_from_timestamp x = !new_guid_from_timestamp x' : ()
$'let format x = !format x' : ()
$'let format_iso8601 x = !format_iso8601 x' : ()