Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Port from_timestamp_millis() (#818) to 0.4.x #823

Merged
merged 3 commits into from Sep 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 1 addition & 2 deletions .github/workflows/lint.yml
Expand Up @@ -2,9 +2,8 @@ name: lint

on:
push:
branches: [main, master]
branches: [main, master, 0.4.x]
pull_request:
branches: [main, master]

jobs:
lint:
Expand Down
4 changes: 1 addition & 3 deletions .github/workflows/test-release.yml
Expand Up @@ -2,9 +2,7 @@ name: Release Test

on:
push:
branches: ["rel*"]
pull_request:
branches: ["rel*"]
branches: ["rel*", "0.4.x"]

# From here down this should be exactly the same as test.yml

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Expand Up @@ -2,7 +2,7 @@ name: All Tests and Builds

on:
push:
branches: [main]
branches: [main, 0.4.x]
pull_request:
paths:
- "**.rs"
Expand Down
43 changes: 43 additions & 0 deletions src/naive/datetime/mod.rs
Expand Up @@ -5,6 +5,7 @@

#[cfg(any(feature = "alloc", feature = "std", test))]
use core::borrow::Borrow;
use core::convert::TryFrom;
use core::ops::{Add, AddAssign, Sub, SubAssign};
use core::{fmt, str};

Expand Down Expand Up @@ -39,6 +40,11 @@ mod tests;
/// touching that call when we are already sure that it WILL overflow...
const MAX_SECS_BITS: usize = 44;

/// Number of nanoseconds in a millisecond
const NANOS_IN_MILLISECOND: u32 = 1_000_000;
/// Number of nanoseconds in a second
const NANOS_IN_SECOND: u32 = 1000 * NANOS_IN_MILLISECOND;

/// The minimum possible `NaiveDateTime`.
#[deprecated(since = "0.4.20", note = "Use NaiveDateTime::MIN instead")]
pub const MIN_DATETIME: NaiveDateTime = NaiveDateTime::MIN;
Expand Down Expand Up @@ -131,6 +137,43 @@ impl NaiveDateTime {
datetime.expect("invalid or out-of-range datetime")
}

/// Creates a new [NaiveDateTime] from milliseconds since the UNIX epoch.
///
/// The UNIX epoch starts on midnight, January 1, 1970, UTC.
///
/// Returns `None` on an out-of-range number of milliseconds.
///
/// # Example
///
/// ```
/// use chrono::NaiveDateTime;
/// let timestamp_millis: i64 = 1662921288; //Sunday, September 11, 2022 6:34:48 PM
/// let naive_datetime = NaiveDateTime::from_timestamp_millis(timestamp_millis);
/// assert!(naive_datetime.is_some());
/// assert_eq!(timestamp_millis, naive_datetime.unwrap().timestamp_millis());
///
/// // Negative timestamps (before the UNIX epoch) are supported as well.
/// let timestamp_millis: i64 = -2208936075; //Mon Jan 01 1900 14:38:45 GMT+0000
/// let naive_datetime = NaiveDateTime::from_timestamp_millis(timestamp_millis);
/// assert!(naive_datetime.is_some());
/// assert_eq!(timestamp_millis, naive_datetime.unwrap().timestamp_millis());
/// ```
#[inline]
pub fn from_timestamp_millis(millis: i64) -> Option<NaiveDateTime> {
let mut secs = millis / 1000;
if millis < 0 {
secs = secs.checked_sub(1)?;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we still need to include this part as well: NANOS_IN_SECOND.checked_sub(nsecs)?, (in the millis < 0 case only)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yeah, good catch. Added a commit that enables CI to run on the 0.4.x branch, too...

}

let nsecs = (millis % 1000).abs();
let mut nsecs = u32::try_from(nsecs).ok()? * NANOS_IN_MILLISECOND;
if secs < 0 {
nsecs = NANOS_IN_SECOND.checked_sub(nsecs)?;
}

NaiveDateTime::from_timestamp_opt(secs, nsecs)
}

/// Makes a new `NaiveDateTime` corresponding to a UTC date and time,
/// from the number of non-leap seconds
/// since the midnight UTC on January 1, 1970 (aka "UNIX timestamp")
Expand Down