mirror of
https://github.com/lune-org/lune.git
synced 2025-04-07 03:50:55 +01:00
Merge 9637c4b731
into 6902ecaa7c
This commit is contained in:
commit
2e1d5ba431
6 changed files with 138 additions and 0 deletions
crates
tests/datetime
types
|
@ -173,6 +173,21 @@ impl DateTime {
|
||||||
Ok(Self { inner })
|
Ok(Self { inner })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Parses a time string in the RFC 2822 format, such as
|
||||||
|
`Tue, 1 Jul 2003 10:52:37 +0200`, into a new `DateTime` struct.
|
||||||
|
|
||||||
|
See [`chrono::DateTime::parse_from_rfc2822`] for additional details.
|
||||||
|
|
||||||
|
# Errors
|
||||||
|
|
||||||
|
Returns an error if the input string is not a valid RFC 2822 date-time.
|
||||||
|
*/
|
||||||
|
pub fn from_rfc_date(rfc_date: impl AsRef<str>) -> DateTimeResult<Self> {
|
||||||
|
let inner = ChronoDateTime::parse_from_rfc2822(rfc_date.as_ref())?.with_timezone(&Utc);
|
||||||
|
Ok(Self { inner })
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Extracts individual date & time values from this
|
Extracts individual date & time values from this
|
||||||
`DateTime`, using the current local time zone.
|
`DateTime`, using the current local time zone.
|
||||||
|
@ -200,6 +215,16 @@ impl DateTime {
|
||||||
pub fn to_iso_date(self) -> String {
|
pub fn to_iso_date(self) -> String {
|
||||||
self.inner.to_rfc3339()
|
self.inner.to_rfc3339()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Formats a time string in the RFC 2822 format, such as `Tue, 1 Jul 2003 10:52:37 +0200`.
|
||||||
|
|
||||||
|
See [`chrono::DateTime::to_rfc2822`] for additional details.
|
||||||
|
*/
|
||||||
|
#[must_use]
|
||||||
|
pub fn to_rfc_date(self) -> String {
|
||||||
|
self.inner.to_rfc2822()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LuaUserData for DateTime {
|
impl LuaUserData for DateTime {
|
||||||
|
@ -230,6 +255,7 @@ impl LuaUserData for DateTime {
|
||||||
);
|
);
|
||||||
// Normal methods
|
// Normal methods
|
||||||
methods.add_method("toIsoDate", |_, this, ()| Ok(this.to_iso_date()));
|
methods.add_method("toIsoDate", |_, this, ()| Ok(this.to_iso_date()));
|
||||||
|
methods.add_method("toRfcDate", |_, this, ()| Ok(this.to_rfc_date()));
|
||||||
methods.add_method(
|
methods.add_method(
|
||||||
"formatUniversalTime",
|
"formatUniversalTime",
|
||||||
|_, this, (format, locale): (Option<String>, Option<String>)| {
|
|_, this, (format, locale): (Option<String>, Option<String>)| {
|
||||||
|
|
|
@ -22,6 +22,9 @@ pub fn module(lua: &Lua) -> LuaResult<LuaTable> {
|
||||||
.with_function("fromIsoDate", |_, iso_date: String| {
|
.with_function("fromIsoDate", |_, iso_date: String| {
|
||||||
Ok(DateTime::from_iso_date(iso_date)?)
|
Ok(DateTime::from_iso_date(iso_date)?)
|
||||||
})?
|
})?
|
||||||
|
.with_function("fromRfcDate", |_, rfc_date: String| {
|
||||||
|
Ok(DateTime::from_rfc_date(rfc_date)?)
|
||||||
|
})?
|
||||||
.with_function("fromLocalTime", |_, values| {
|
.with_function("fromLocalTime", |_, values| {
|
||||||
Ok(DateTime::from_local_time(&values)?)
|
Ok(DateTime::from_local_time(&values)?)
|
||||||
})?
|
})?
|
||||||
|
|
|
@ -92,11 +92,13 @@ create_tests! {
|
||||||
datetime_format_local_time: "datetime/formatLocalTime",
|
datetime_format_local_time: "datetime/formatLocalTime",
|
||||||
datetime_format_universal_time: "datetime/formatUniversalTime",
|
datetime_format_universal_time: "datetime/formatUniversalTime",
|
||||||
datetime_from_iso_date: "datetime/fromIsoDate",
|
datetime_from_iso_date: "datetime/fromIsoDate",
|
||||||
|
datetime_from_rfc_date: "datetime/fromRfcDate",
|
||||||
datetime_from_local_time: "datetime/fromLocalTime",
|
datetime_from_local_time: "datetime/fromLocalTime",
|
||||||
datetime_from_universal_time: "datetime/fromUniversalTime",
|
datetime_from_universal_time: "datetime/fromUniversalTime",
|
||||||
datetime_from_unix_timestamp: "datetime/fromUnixTimestamp",
|
datetime_from_unix_timestamp: "datetime/fromUnixTimestamp",
|
||||||
datetime_now: "datetime/now",
|
datetime_now: "datetime/now",
|
||||||
datetime_to_iso_date: "datetime/toIsoDate",
|
datetime_to_iso_date: "datetime/toIsoDate",
|
||||||
|
datetime_to_rfc_date: "datetime/toRfcDate",
|
||||||
datetime_to_local_time: "datetime/toLocalTime",
|
datetime_to_local_time: "datetime/toLocalTime",
|
||||||
datetime_to_universal_time: "datetime/toUniversalTime",
|
datetime_to_universal_time: "datetime/toUniversalTime",
|
||||||
}
|
}
|
||||||
|
|
11
tests/datetime/fromRfcDate.luau
Normal file
11
tests/datetime/fromRfcDate.luau
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
local DateTime = require("@lune/datetime")
|
||||||
|
|
||||||
|
assert(
|
||||||
|
DateTime.fromRfcDate("Fri, 21 Nov 1997 09:55:06 -0600") ~= nil,
|
||||||
|
"expected DateTime.fromRfcDate() to return DateTime, got nil"
|
||||||
|
)
|
||||||
|
|
||||||
|
assert(
|
||||||
|
DateTime.fromRfcDate("Tue, 1 Jul 2003 10:52:37 +0200") ~= nil,
|
||||||
|
"expected DateTime.fromRfcDate() to return DateTime, got nil"
|
||||||
|
)
|
51
tests/datetime/toRfcDate.luau
Normal file
51
tests/datetime/toRfcDate.luau
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
local DateTime = require("@lune/datetime")
|
||||||
|
|
||||||
|
local now = DateTime.now()
|
||||||
|
local nowRfc = now:toRfcDate()
|
||||||
|
|
||||||
|
assert(type(nowRfc) == "string", "toRfcDate should return a string")
|
||||||
|
assert(
|
||||||
|
string.match(nowRfc, "^%a%a%a, %d%d? %a%a%a %d%d%d%d %d%d:%d%d:%d%d [+-]%d%d%d%d$"),
|
||||||
|
"RFC 2822 date string does not match expected format"
|
||||||
|
)
|
||||||
|
|
||||||
|
-- Extract components of the RFC 2822 string
|
||||||
|
local day, date, month, year, time, timezone =
|
||||||
|
nowRfc:match("^(%a%a%a), (%d%d?) (%a%a%a) (%d%d%d%d) (%d%d:%d%d:%d%d) ([+-]%d%d%d%d)$")
|
||||||
|
|
||||||
|
if not day or not date or not month or not year or not time or not timezone then
|
||||||
|
error("Failed to extract components from RFC 2822 date string")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Validate month
|
||||||
|
local validMonths = {
|
||||||
|
Jan = true, Feb = true, Mar = true, Apr = true, May = true, Jun = true,
|
||||||
|
Jul = true, Aug = true, Sep = true, Oct = true, Nov = true, Dec = true,
|
||||||
|
}
|
||||||
|
assert(validMonths[month], "Month must be a valid RFC 2822 month abbreviation")
|
||||||
|
|
||||||
|
-- Validate year
|
||||||
|
assert(string.match(year, "^%d%d%d%d$"), "Year must be a 4-digit number")
|
||||||
|
|
||||||
|
-- Validate date
|
||||||
|
local dayNum = tonumber(date)
|
||||||
|
assert(dayNum >= 1 and dayNum <= 31, "Date must be between 1 and 31")
|
||||||
|
|
||||||
|
-- Validate time
|
||||||
|
local hour, minute, second = time:match("^(%d%d):(%d%d):(%d%d)$")
|
||||||
|
if not hour or not minute or not second then
|
||||||
|
error("Failed to extract time components from RFC 2822 date string")
|
||||||
|
end
|
||||||
|
|
||||||
|
assert(hour and tonumber(hour) >= 0 and tonumber(hour) < 24, "Hour must be between 0 and 23")
|
||||||
|
assert(minute and tonumber(minute) >= 0 and tonumber(minute) < 60, "Minute must be between 0 and 59")
|
||||||
|
assert(second and tonumber(second) >= 0 and tonumber(second) < 60, "Second must be between 0 and 59")
|
||||||
|
|
||||||
|
-- Validate timezone
|
||||||
|
local tzHour, tzMinute = timezone:match("^([+-]%d%d)(%d%d)$")
|
||||||
|
if not tzHour or not tzMinute then
|
||||||
|
error("Failed to extract timezone components from RFC 2822 date string")
|
||||||
|
end
|
||||||
|
|
||||||
|
assert(tzHour and tonumber(tzHour) >= -14 and tonumber(tzHour) <= 14, "Timezone hour offset must be between -14 and +14")
|
||||||
|
assert(tzMinute and tonumber(tzMinute) >= 0 and tonumber(tzMinute) < 60, "Timezone minute offset must be between 0 and 59")
|
|
@ -189,6 +189,24 @@ function DateTime.toIsoDate(self: DateTime): string
|
||||||
return nil :: any
|
return nil :: any
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--[=[
|
||||||
|
@within DateTime
|
||||||
|
@tag Method
|
||||||
|
|
||||||
|
Formats this `DateTime` as an RFC 2822 date-time string.
|
||||||
|
|
||||||
|
Some examples of RFC 2822 date-time strings are:
|
||||||
|
|
||||||
|
- `Fri, 21 Nov 1997 09:55:06 -0600`
|
||||||
|
- `Tue, 1 Jul 2003 10:52:37 +0200`
|
||||||
|
- `Mon, 23 Dec 2024 01:58:48 GMT`
|
||||||
|
|
||||||
|
@return string -- The RFC 2822 formatted string
|
||||||
|
]=]
|
||||||
|
function DateTime.toRfcDate(self: DateTime): string
|
||||||
|
return nil :: any
|
||||||
|
end
|
||||||
|
|
||||||
--[=[
|
--[=[
|
||||||
@within DateTime
|
@within DateTime
|
||||||
@tag Method
|
@tag Method
|
||||||
|
@ -255,6 +273,9 @@ export type DateTime = typeof(DateTime)
|
||||||
-- Formats the current moment in time as an ISO 8601 string
|
-- Formats the current moment in time as an ISO 8601 string
|
||||||
print(now:toIsoDate())
|
print(now:toIsoDate())
|
||||||
|
|
||||||
|
-- Formats the current moment in time as an RFC 2822 string
|
||||||
|
print(now:toRfcDate())
|
||||||
|
|
||||||
-- Formats the current moment in time, using the local
|
-- Formats the current moment in time, using the local
|
||||||
-- time, the French locale, and the specified time string
|
-- time, the French locale, and the specified time string
|
||||||
print(now:formatLocalTime("%A, %d %B %Y", "fr"))
|
print(now:formatLocalTime("%A, %d %B %Y", "fr"))
|
||||||
|
@ -414,4 +435,28 @@ function dateTime.fromIsoDate(isoDate: string): DateTime
|
||||||
return nil :: any
|
return nil :: any
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--[=[
|
||||||
|
@within DateTime
|
||||||
|
@tag Constructor
|
||||||
|
|
||||||
|
Creates a new `DateTime` from an RFC 2822 date-time string.
|
||||||
|
|
||||||
|
### Errors
|
||||||
|
|
||||||
|
This constructor is fallible and may throw an error if the given
|
||||||
|
string does not strictly follow the RFC 2822 date-time string format.
|
||||||
|
|
||||||
|
Some examples of valid RFC 2822 date-time strings are:
|
||||||
|
|
||||||
|
- `Fri, 21 Nov 1997 09:55:06 -0600`
|
||||||
|
- `Tue, 1 Jul 2003 10:52:37 +0200`
|
||||||
|
- `Mon, 23 Dec 2024 01:58:48 GMT`
|
||||||
|
|
||||||
|
@param rfcDate -- An RFC 2822 formatted string
|
||||||
|
@return DateTime -- The new DateTime object
|
||||||
|
]=]
|
||||||
|
function dateTime.fromRfcDate(rfcDate: string): DateTime
|
||||||
|
return nil :: any
|
||||||
|
end
|
||||||
|
|
||||||
return dateTime
|
return dateTime
|
||||||
|
|
Loading…
Add table
Reference in a new issue