Enforce some more consistency with new datetime changes + add deprecation warning to iso methods

This commit is contained in:
Filip Tibell 2025-04-23 16:01:12 +02:00
parent d6f4cb289e
commit 8ffbb328f3
No known key found for this signature in database
9 changed files with 77 additions and 126 deletions

View file

@ -159,7 +159,7 @@ impl DateTime {
}
/**
Parses a time string in the ISO 8601 format, such as
Parses a time string in the RFC 3339 format, such as
`1996-12-19T16:39:57-08:00`, into a new `DateTime` struct.
See [`chrono::DateTime::parse_from_rfc3339`] for additional details.
@ -168,8 +168,8 @@ impl DateTime {
Returns an error if the input string is not a valid RFC 3339 date-time.
*/
pub fn from_iso_date(iso_date: impl AsRef<str>) -> DateTimeResult<Self> {
let inner = ChronoDateTime::parse_from_rfc3339(iso_date.as_ref())?.with_timezone(&Utc);
pub fn from_rfc_3339(date: impl AsRef<str>) -> DateTimeResult<Self> {
let inner = ChronoDateTime::parse_from_rfc3339(date.as_ref())?.with_timezone(&Utc);
Ok(Self { inner })
}
@ -183,8 +183,8 @@ impl DateTime {
Returns an error if the input string is not a valid RFC 2822 date-time.
*/
pub fn from_rfc_2822_date(rfc_date: impl AsRef<str>) -> DateTimeResult<Self> {
let inner = ChronoDateTime::parse_from_rfc2822(rfc_date.as_ref())?.with_timezone(&Utc);
pub fn from_rfc_2822(date: impl AsRef<str>) -> DateTimeResult<Self> {
let inner = ChronoDateTime::parse_from_rfc2822(date.as_ref())?.with_timezone(&Utc);
Ok(Self { inner })
}
@ -207,12 +207,12 @@ impl DateTime {
}
/**
Formats a time string in the ISO 8601 format, such as `1996-12-19T16:39:57-08:00`.
Formats a time string in the RFC 3339 format, such as `1996-12-19T16:39:57-08:00`.
See [`chrono::DateTime::to_rfc3339`] for additional details.
*/
#[must_use]
pub fn to_iso_date(self) -> String {
pub fn to_rfc_3339(self) -> String {
self.inner.to_rfc3339()
}
@ -222,7 +222,7 @@ impl DateTime {
See [`chrono::DateTime::to_rfc2822`] for additional details.
*/
#[must_use]
pub fn to_rfc_2822_date(self) -> String {
pub fn to_rfc_2822(self) -> String {
self.inner.to_rfc2822()
}
}
@ -254,9 +254,9 @@ impl LuaUserData for DateTime {
},
);
// Normal methods
methods.add_method("toIsoDate", |_, this, ()| Ok(this.to_iso_date()));
methods.add_method("toRfc3339", |_, this, ()| Ok(this.to_iso_date()));
methods.add_method("toRfc2822", |_, this, ()| Ok(this.to_rfc_2822_date()));
methods.add_method("toIsoDate", |_, this, ()| Ok(this.to_rfc_3339())); // FUTURE: Remove this rfc3339 alias method
methods.add_method("toRfc3339", |_, this, ()| Ok(this.to_rfc_3339()));
methods.add_method("toRfc2822", |_, this, ()| Ok(this.to_rfc_2822()));
methods.add_method(
"formatUniversalTime",
|_, this, (format, locale): (Option<String>, Option<String>)| {

View file

@ -19,14 +19,14 @@ pub use self::date_time::DateTime;
*/
pub fn module(lua: Lua) -> LuaResult<LuaTable> {
TableBuilder::new(lua)?
.with_function("fromIsoDate", |_, iso_date: String| {
Ok(DateTime::from_iso_date(iso_date)?)
.with_function("fromIsoDate", |_, date: String| {
Ok(DateTime::from_rfc_3339(date)?) // FUTURE: Remove this rfc3339 alias method
})?
.with_function("fromRfc3339", |_, iso_date: String| {
Ok(DateTime::from_iso_date(iso_date)?)
.with_function("fromRfc3339", |_, date: String| {
Ok(DateTime::from_rfc_3339(date)?)
})?
.with_function("fromRfc2822", |_, rfc_date: String| {
Ok(DateTime::from_rfc_2822_date(rfc_date)?)
.with_function("fromRfc2822", |_, date: String| {
Ok(DateTime::from_rfc_2822(date)?)
})?
.with_function("fromLocalTime", |_, values| {
Ok(DateTime::from_local_time(&values)?)

View file

@ -91,15 +91,14 @@ create_tests! {
create_tests! {
datetime_format_local_time: "datetime/formatLocalTime",
datetime_format_universal_time: "datetime/formatUniversalTime",
datetime_from_iso_date: "datetime/fromIsoDate",
datetime_from_rfc_2822_date: "datetime/fromRfc2822",
datetime_from_rfc_3339_date: "datetime/fromRfc3339",
datetime_from_rfc_2822: "datetime/fromRfc2822",
datetime_from_rfc_3339: "datetime/fromRfc3339",
datetime_from_local_time: "datetime/fromLocalTime",
datetime_from_universal_time: "datetime/fromUniversalTime",
datetime_from_unix_timestamp: "datetime/fromUnixTimestamp",
datetime_now: "datetime/now",
datetime_to_iso_date: "datetime/toIsoDate",
datetime_to_rfc_2822_date: "datetime/toRfc2822",
datetime_to_rfc_2822: "datetime/toRfc2822",
datetime_to_rfc_3339: "datetime/toRfc3339",
datetime_to_local_time: "datetime/toLocalTime",
datetime_to_universal_time: "datetime/toUniversalTime",
}

View file

@ -1,11 +0,0 @@
local DateTime = require("@lune/datetime")
assert(
DateTime.fromIsoDate("2023-08-26T16:56:28Z") ~= nil,
"expected DateTime.fromIsoDate() to return DateTime, got nil"
)
assert(
DateTime.fromIsoDate("1929-12-05T23:18:23Z") ~= nil,
"expected DateTime.fromIsoDate() to return DateTime, got nil"
)

View file

@ -2,10 +2,10 @@ local DateTime = require("@lune/datetime")
assert(
DateTime.fromRfc3339("2023-08-26T16:56:28Z") ~= nil,
"expected DateTime.fromIsoDate() to return DateTime, got nil"
"expected DateTime.fromRfc3339() to return DateTime, got nil"
)
assert(
DateTime.fromRfc3339("1929-12-05T23:18:23Z") ~= nil,
"expected DateTime.fromIsoDate() to return DateTime, got nil"
"expected DateTime.fromRfc3339() to return DateTime, got nil"
)

View file

@ -1,30 +1,12 @@
local DateTime = require("@lune/datetime")
local values = DateTime.fromIsoDate("2023-08-27T05:54:19Z"):toLocalTime()
local values = DateTime.fromRfc3339("2023-08-27T05:54:19Z"):toLocalTime()
local expectedDateTimeValues = os.date("*t", 1693115659)
assert(
values.year == expectedDateTimeValues.year,
`expected {values.year} == {expectedDateTimeValues.year}`
)
assert(
values.month == expectedDateTimeValues.month,
`expected {values.month} == {expectedDateTimeValues.month}`
)
assert(
values.day == expectedDateTimeValues.day,
`expected {values.day} == {expectedDateTimeValues.day}`
)
assert(
values.hour == expectedDateTimeValues.hour,
`expected {values.hour} == {expectedDateTimeValues.hour}`
)
assert(
values.minute == expectedDateTimeValues.min,
`expected {values.minute} == {expectedDateTimeValues.min}`
)
assert(
values.second == expectedDateTimeValues.sec,
`expected {values.second} == {expectedDateTimeValues.sec}`
)
assert(values.year == expectedDateTimeValues.year, `expected {values.year} == {expectedDateTimeValues.year}`)
assert(values.month == expectedDateTimeValues.month, `expected {values.month} == {expectedDateTimeValues.month}`)
assert(values.day == expectedDateTimeValues.day, `expected {values.day} == {expectedDateTimeValues.day}`)
assert(values.hour == expectedDateTimeValues.hour, `expected {values.hour} == {expectedDateTimeValues.hour}`)
assert(values.minute == expectedDateTimeValues.min, `expected {values.minute} == {expectedDateTimeValues.min}`)
assert(values.second == expectedDateTimeValues.sec, `expected {values.second} == {expectedDateTimeValues.sec}`)

View file

@ -1,35 +1,26 @@
local DateTime = require("@lune/datetime")
local now = DateTime.now()
local nowIso = now:toIsoDate()
local nowRfc = now:toRfc3339()
-- Make sure we have separator characters, T to separate date & time, + or Z to separate timezone
local dateTimeSplitIdx = string.find(nowIso, "T")
local timezoneSplitIdx = string.find(nowIso, "+")
local timezoneZeroedIdx = string.find(nowIso, "Z")
local dateTimeSplitIdx = string.find(nowRfc, "T")
local timezoneSplitIdx = string.find(nowRfc, "+")
local timezoneZeroedIdx = string.find(nowRfc, "Z")
assert(dateTimeSplitIdx ~= nil, "Missing date & time separator 'T' in iso 8601 string")
assert(
timezoneSplitIdx ~= nil or timezoneZeroedIdx ~= nil,
"Missing timezone separator '+' or 'Z' in iso date string"
)
assert(dateTimeSplitIdx ~= nil, "Missing date & time separator 'T' in RFC 3339 string")
assert(timezoneSplitIdx ~= nil or timezoneZeroedIdx ~= nil, "Missing timezone separator '+' or 'Z' in RFC 3339 string")
-- Split date (before T) by dashes, split time (after T, before + or Z)
-- by colons, we should then get 3 substrings for each of date & time
local dateParts = string.split(string.sub(nowIso, 1, dateTimeSplitIdx - 1), "-")
local timeParts = string.split(
string.sub(
nowIso,
dateTimeSplitIdx + 1,
((timezoneSplitIdx or timezoneZeroedIdx) :: number) - 1
),
":"
)
local dateParts = string.split(string.sub(nowRfc, 1, dateTimeSplitIdx - 1), "-")
local timeParts =
string.split(string.sub(nowRfc, dateTimeSplitIdx + 1, ((timezoneSplitIdx or timezoneZeroedIdx) :: number) - 1), ":")
assert(#dateParts == 3, "Date partial of iso 8601 should consist of 3 substrings, separated by '-'")
assert(#timeParts == 3, "Time partial of iso 8601 should consist of 3 substrings, separated by ':'")
assert(#dateParts == 3, "Date partial of RFC 3339 should consist of 3 substrings, separated by '-'")
assert(#timeParts == 3, "Time partial of RFC 3339 should consist of 3 substrings, separated by ':'")
-- date should be in format YYYY:MM::DD
-- time should be in format HH:MM:SS with optional fraction for seconds
@ -51,22 +42,13 @@ assert(
if timezoneZeroedIdx ~= nil then
-- No timezone offset
assert(
timezoneZeroedIdx == #nowIso,
"Timezone specifier 'Z' must be at the last character in iso 8601 string"
)
assert(timezoneZeroedIdx == #nowRfc, "Timezone specifier 'Z' must be at the last character in RFC 3339 string")
elseif timezoneSplitIdx ~= nil then
-- Timezone offset
local timezoneParts = string.split(string.sub(nowIso, timezoneSplitIdx + 1), ":")
local timezoneParts = string.split(string.sub(nowRfc, timezoneSplitIdx + 1), ":")
assert(#timezoneParts == 2, "Timezone partial should consist of 2 substings, separated by ':'")
assert(
string.match(timezoneParts[1], "^%d%d$"),
"Timezone partial should have 2 digits for hour"
)
assert(
string.match(timezoneParts[2], "^%d%d$"),
"Timezone partial should have 2 digits for minute"
)
assert(string.match(timezoneParts[1], "^%d%d$"), "Timezone partial should have 2 digits for hour")
assert(string.match(timezoneParts[2], "^%d%d$"), "Timezone partial should have 2 digits for minute")
else
error("unreachable")
end

View file

@ -1,30 +1,12 @@
local DateTime = require("@lune/datetime")
local values = DateTime.fromIsoDate("2023-08-27T05:54:19Z"):toLocalTime()
local values = DateTime.fromRfc3339("2023-08-27T05:54:19Z"):toLocalTime()
local expectedDateTimeValues = os.date("*t", 1693115659)
assert(
values.year == expectedDateTimeValues.year,
`expected {values.year} == {expectedDateTimeValues.year}`
)
assert(
values.month == expectedDateTimeValues.month,
`expected {values.month} == {expectedDateTimeValues.month}`
)
assert(
values.day == expectedDateTimeValues.day,
`expected {values.day} == {expectedDateTimeValues.day}`
)
assert(
values.hour == expectedDateTimeValues.hour,
`expected {values.hour} == {expectedDateTimeValues.hour}`
)
assert(
values.minute == expectedDateTimeValues.min,
`expected {values.minute} == {expectedDateTimeValues.min}`
)
assert(
values.second == expectedDateTimeValues.sec,
`expected {values.second} == {expectedDateTimeValues.sec}`
)
assert(values.year == expectedDateTimeValues.year, `expected {values.year} == {expectedDateTimeValues.year}`)
assert(values.month == expectedDateTimeValues.month, `expected {values.month} == {expectedDateTimeValues.month}`)
assert(values.day == expectedDateTimeValues.day, `expected {values.day} == {expectedDateTimeValues.day}`)
assert(values.hour == expectedDateTimeValues.hour, `expected {values.hour} == {expectedDateTimeValues.hour}`)
assert(values.minute == expectedDateTimeValues.min, `expected {values.minute} == {expectedDateTimeValues.min}`)
assert(values.second == expectedDateTimeValues.sec, `expected {values.second} == {expectedDateTimeValues.sec}`)

View file

@ -163,11 +163,7 @@ end
@param locale -- The locale the time should be formatted in
@return string -- The formatting string
]=]
function DateTime.formatUniversalTime(
self: DateTime,
formatString: string?,
locale: Locale?
): string
function DateTime.formatUniversalTime(self: DateTime, formatString: string?, locale: Locale?): string
return nil :: any
end
@ -175,6 +171,8 @@ end
@within DateTime
@tag Method
**DEPRECATED**: Use `DateTime.toRfc3339` instead.
Formats this `DateTime` as an ISO 8601 date-time string.
Some examples of ISO 8601 date-time strings are:
@ -207,6 +205,24 @@ function DateTime.toRfc2822(self: DateTime): string
return nil :: any
end
--[=[
@within DateTime
@tag Method
Formats this `DateTime` as an RFC 3339 date-time string.
Some examples of RFC 3339 date-time strings are:
- `2020-02-22T18:12:08Z`
- `2000-01-31T12:34:56+05:00`
- `1970-01-01T00:00:00.055Z`
@return string -- The RFC 3339 formatted string
]=]
function DateTime.toRfc3339(self: DateTime): string
return nil :: any
end
--[=[
@within DateTime
@tag Method
@ -270,8 +286,8 @@ export type DateTime = typeof(DateTime)
-- Creates a DateTime for the current exact moment in time
local now = DateTime.now()
-- Formats the current moment in time as an ISO 8601 string
print(now:toIsoDate())
-- Formats the current moment in time as an RFC 3339 string
print(now:toRfc3339())
-- Formats the current moment in time as an RFC 2822 string
print(now:toRfc2822())
@ -415,8 +431,9 @@ end
@within DateTime
@tag Constructor
**DEPRECATED**: Use `DateTime.fromRfc3339` instead.
Creates a new `DateTime` from an ISO 8601 date-time string.
This function behaves the same as `fromRfc3339`.
### Errors