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

Simplify from_timestamp_millis, from_timestamp_micros #1032

Merged
merged 1 commit into from
May 15, 2023

Conversation

pitdicker
Copy link
Collaborator

These methods are trivial when using div_euclid and rem_euclid. But the current somewhat complex implementation predates those methods in the standard library.

The panic in #934 related to this code did not reproduce, but I included it as a test case.

Closes #934.

@pitdicker
Copy link
Collaborator Author

Hmm, the keywords 'closes' and 'fixes' only work when the PR targets the default branch.

@esheppa
Copy link
Collaborator

esheppa commented Apr 22, 2023

Thanks for this @pitdicker - there are probably a few other places with similar logic that can be replaced as well given this works! (I'll look into the CI failures as they aren't caused by this PR).

#1033 should fix the CI failures here

@pitdicker
Copy link
Collaborator Author

@esheppa I didn't find other places yet, but your comment put me on track to find some simplification that allow removing the num-integer dependency in #1037.

Copy link
Contributor

@jtmoon79 jtmoon79 left a comment

Choose a reason for hiding this comment

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

Should test cases be added that compare results of the "old way" and this "new way"?

I'd feel more comfortable with this if it proved it didn't break anything.

e.g.

/// compare old way of converting from millisconds using `_from_timestamp_unit`
/// to new way using `from_timestamp_millis`.
/// Prove they are equivalent.
#[test]
fn test_old__from_timestamp_unit_to_new_from_timestamp_millis {
    let cmp_millis = |x| assert_eq!(Self::_from_timestamp_unit(x, TimestampUnit::Millis), Self::from_timestamp_millis(x));
    cmp_millis(0);
    cmp_millis(1);
    cmp_millis(2);
    cmp_millis(998);
    cmp_millis(999);
    cmp_millis(1_000);
    cmp_millis(1_001);
    cmp_millis(1_002);
    cmp_millis(999_998);
    cmp_millis(999_999);
    cmp_millis(1_000_000);
    cmp_millis(1_000_001);
    cmp_millis(1_000_002);
    cmp_millis(1682489137231); // Wednesday, April 26, 2023 6:05:37.231Z
    cmp_millis(MAX - 2);
    cmp_millis(MAX - 1);
    cmp_millis(MAX);
}

/// OLD METHOD; DO NOT USE. ONLY KEPT AROUND TO PROVE `from_timestamp_millis` AND `from_timestamp_micros` PERFORM EQUIVALENTLY.
/// Creates a new [NaiveDateTime] from milliseconds or microseconds since the UNIX epoch.
///
/// This is a private function used by [from_timestamp_millis] and [from_timestamp_micros].
fn _from_timestamp_unit(...) {

Same test for the microseconds version.
...though, I wonder if there is already such a test case but at a higher level (i.e. input a Epoch timestamp, assert output datetime result)? 👀

@pitdicker
Copy link
Collaborator Author

I'll look at what tests are covering this and otherwise add one 👍

@pitdicker
Copy link
Collaborator Author

I wonder what happened to my commit with a test for #934, must have lost it somewhere...

The existing test for these methods are naive::datetime::NaiveDateTime::from_timestamp_millis and naive::datetime::NaiveDateTime::from_timestamp_micros, and the doctests. I extended them with your test cases.

/// OLD METHOD; DO NOT USE. ONLY KEPT AROUND TO PROVE `from_timestamp_millis` AND `from_timestamp_micros` PERFORM EQUIVALENTLY.
/// Creates a new [NaiveDateTime] from milliseconds or microseconds since the UNIX epoch.
///
/// This is a private function used by [from_timestamp_millis] and [from_timestamp_micros].
fn _from_timestamp_unit(...) {

Honestly, I don't feel like what these methods warrants more complex tests. Adding them is no problem, it just feels out of place.

@jtmoon79
Copy link
Contributor

jtmoon79 commented Apr 28, 2023

I wonder what happened to my commit with a test for #934, must have lost it somewhere...

The existing test for these methods are naive::datetime::NaiveDateTime::from_timestamp_millis and naive::datetime::NaiveDateTime::from_timestamp_micros, and the doctests. I extended them with your test cases.

/// OLD METHOD; DO NOT USE. ONLY KEPT AROUND TO PROVE `from_timestamp_millis` AND `from_timestamp_micros` PERFORM EQUIVALENTLY.
/// Creates a new [NaiveDateTime] from milliseconds or microseconds since the UNIX epoch.
///
/// This is a private function used by [from_timestamp_millis] and [from_timestamp_micros].
fn _from_timestamp_unit(...) {

Honestly, I don't feel like what these methods warrants more complex tests. Adding them is no problem, it just feels out of place.

Yeah, my suggestion get's kinda' ugly.

What about this:

  • commit A: add test cases for current code
    #[test]
    fn test_from_timestamp_millis() {
        assert_eq!(Self::from_timestamp_millis(0), Some(ymdhms(1970, 1, 1, 0, 0, 0));
        assert_eq!(Self::from_timestamp_millis(1), Some(...));
        assert_eq!(Self::from_timestamp_millis(2), Some(...));
        assert_eq!(Self::from_timestamp_millis(998), Some(...));
        assert_eq!(Self::from_timestamp_millis(999), Some(...));
        assert_eq!(Self::from_timestamp_millis(1_000), Some(...));
        assert_eq!(Self::from_timestamp_millis(1_001), Some(...));
        assert_eq!(Self::from_timestamp_millis(1_002), Some(...));
        assert_eq!(Self::from_timestamp_millis(999_998), Some(...));
        assert_eq!(Self::from_timestamp_millis(999_999), Some(...));
        assert_eq!(Self::from_timestamp_millis(1_000_000), Some(...));
        assert_eq!(Self::from_timestamp_millis(1_000_001), Some(...));
        assert_eq!(Self::from_timestamp_millis(1_000_002), Some(...));
        assert_eq!(Self::from_timestamp_millis(1682489137231), Some(...)); // Wednesday, April 26, 2023 6:05:37.231Z
        // ...
        // more asserts, get creative!
        // ...
        assert_eq!(Self::from_timestamp_millis(MAX - 2), Some(...));
        assert_eq!(Self::from_timestamp_millis(MAX - 1), Some(...));
        assert_eq!(Self::from_timestamp_millis(MAX), Some(...));
        // None cases
        assert_eq!(Self::from_timestamp_millis(???), None);
    }
    
    #[test]
    fn test_from_timestamp_micros() {
       // asserts!
       // ...
       // assert_eq!(Self::from_timestamp_micros(x), y)
       // ...
    }
  • commit B: make changes proposed in this PR, prior-added test cases should not affected

@pitdicker
Copy link
Collaborator Author

😄 Yes, I added the test in a commit before the changes so it was easy to test the old and new implementation. a419c4b

more asserts, get creative!

Probably dates before 1970 are interesting to test.

@jtmoon79
Copy link
Contributor

😄 Yes, I added the test in a commit before the changes so it was easy to test the old and new implementation. a419c4b

more asserts, get creative!

Probably dates before 1970 are interesting to test.

Oh for some reason I had entirely overlooked that commit (and tests). But yeah, a few more wouldn't hurt; up to you.

@djc
Copy link
Member

djc commented May 15, 2023

Going to merge this with the existing test coverage for now, thanks!

@djc djc merged commit 0367c76 into chronotope:0.4.x May 15, 2023
@pitdicker pitdicker deleted the from_timestamp branch May 15, 2023 10:23
crapStone pushed a commit to Calciumdibromid/CaBr2 that referenced this pull request Jun 12, 2023
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [chrono](https://github.com/chronotope/chrono) | dependencies | patch | `0.4.24` -> `0.4.26` |

---

### Release Notes

<details>
<summary>chronotope/chrono</summary>

### [`v0.4.26`](https://github.com/chronotope/chrono/releases/tag/v0.4.26): 0.4.26

[Compare Source](chronotope/chrono@v0.4.25...v0.4.26)

The changes from [#&#8203;807](chronotope/chrono#807) we merged for 0.4.25 unfortunately restricted parsing in a way that was incompatible with earlier 0.4.x releases. We reverted this in [#&#8203;1113](chronotope/chrono#1113). A small amount of other changes were merged since.

-   Update README ([#&#8203;1111](chronotope/chrono#1111), thanks to [@&#8203;pitdicker](https://github.com/pitdicker))
-   Revert backport of [#&#8203;807](chronotope/chrono#807) ([#&#8203;1113](chronotope/chrono#1113), thanks to [@&#8203;pitdicker](https://github.com/pitdicker))
-   Update to 2021 edition ([#&#8203;1109](chronotope/chrono#1109), thanks to [@&#8203;tottoto](https://github.com/tottoto))
-   Fix `DurationRound` panics from issue [#&#8203;1010](chronotope/chrono#1010) ([#&#8203;1093](chronotope/chrono#1093), thanks to [@&#8203;pitdicker](https://github.com/pitdicker))
-   tests: date path consolidate (branch 0.4.x) ([#&#8203;1090](chronotope/chrono#1090), thanks to [@&#8203;jtmoon79](https://github.com/jtmoon79))
-   Parse tests nanosecond bare dot (branch 0.4.x) ([#&#8203;1098](chronotope/chrono#1098), thanks to [@&#8203;jtmoon79](https://github.com/jtmoon79))
-   yamllint cleanup lint.yml test.yml ([#&#8203;1102](chronotope/chrono#1102), thanks to [@&#8203;jtmoon79](https://github.com/jtmoon79))
-   Remove num-iter dependency ([#&#8203;1107](chronotope/chrono#1107), thanks to [@&#8203;tottoto](https://github.com/tottoto))

Thanks on behalf of the chrono team ([@&#8203;djc](https://github.com/djc) and [@&#8203;esheppa](https://github.com/esheppa)) to all contributors!

### [`v0.4.25`](https://github.com/chronotope/chrono/releases/tag/v0.4.25): 0.4.25

[Compare Source](chronotope/chrono@v0.4.24...v0.4.25)

Time for another maintenance release. This release bumps the MSRV to 1.56; given MSRV bumps in chrono's dependencies (notably for syn 2), we felt that it no longer made sense to support any older versions. Feedback welcome in our issue tracker!

##### Additions

-   Bump the MSRV to 1.56 ([#&#8203;1053](chronotope/chrono#1053))
-   Apply comments from MSRV bump ([#&#8203;1026](chronotope/chrono#1026), thanks to [@&#8203;pitdicker](https://github.com/pitdicker))
-   Remove num-integer dependency ([#&#8203;1037](chronotope/chrono#1037), thanks to [@&#8203;pitdicker](https://github.com/pitdicker))
-   Add `NaiveDateTime::and_utc()` method ([#&#8203;952](chronotope/chrono#952), thanks to [@&#8203;klnusbaum](https://github.com/klnusbaum))
-   derive `Hash` for most pub types that also derive `PartialEq` ([#&#8203;938](chronotope/chrono#938), thanks to [@&#8203;bruceg](https://github.com/bruceg))
-   Add `parse_and_remainder()` methods ([#&#8203;1011](chronotope/chrono#1011), thanks to [@&#8203;pitdicker](https://github.com/pitdicker))
-   Add `DateTime::fix_offset()` ([#&#8203;1030](chronotope/chrono#1030), thanks to [@&#8203;pitdicker](https://github.com/pitdicker))
-   Add `#[track_caller]` to `LocalResult::unwrap` ([#&#8203;1046](chronotope/chrono#1046), thanks to [@&#8203;pitdicker](https://github.com/pitdicker))
-   Add `#[must_use]` to some methods ([#&#8203;1007](chronotope/chrono#1007), thanks to [@&#8203;aceArt-GmbH](https://github.com/aceArt-GmbH))
-   Implement `PartialOrd` for `Month` ([#&#8203;999](chronotope/chrono#999), thanks to [@&#8203;Munksgaard](https://github.com/Munksgaard))
-   Add `impl From<NaiveDateTime> for NaiveDate` ([#&#8203;1012](chronotope/chrono#1012), thanks to [@&#8203;pezcore](https://github.com/pezcore))
-   Extract timezone info from tzdata file on Android ([#&#8203;978](chronotope/chrono#978), thanks to [@&#8203;RumovZ](https://github.com/RumovZ))

##### Fixes

-   Prevent string slicing inside char boundaries ([#&#8203;1024](chronotope/chrono#1024), thanks to [@&#8203;pitdicker](https://github.com/pitdicker))
-   fix IsoWeek so that its flags are always correct ([#&#8203;991](chronotope/chrono#991), thanks to [@&#8203;moshevds](https://github.com/moshevds))
-   Fix out-of-range panic in `NaiveWeek::last_day` ([#&#8203;1070](chronotope/chrono#1070), thanks to [@&#8203;pitdicker](https://github.com/pitdicker))
-   Use correct offset in conversion from `Local` to `FixedOffset` ([#&#8203;1041](chronotope/chrono#1041), thanks to [@&#8203;pitdicker](https://github.com/pitdicker))
-   Fix military timezones in RFC 2822 parsing ([#&#8203;1013](chronotope/chrono#1013), thanks to [@&#8203;pitdicker](https://github.com/pitdicker))
-   Guard against overflow in NaiveDate::with_\*0 methods ([#&#8203;1023](chronotope/chrono#1023), thanks to [@&#8203;pitdicker](https://github.com/pitdicker))
-   Fix panic in from_num_days_from_ce_opt ([#&#8203;1052](chronotope/chrono#1052), thanks to [@&#8203;pitdicker](https://github.com/pitdicker))

##### Refactoring

-   Rely on std for getting local time offset ([#&#8203;1072](chronotope/chrono#1072), thanks to [@&#8203;pitdicker](https://github.com/pitdicker))
-   Make functions in internals const ([#&#8203;1043](chronotope/chrono#1043), thanks to [@&#8203;pitdicker](https://github.com/pitdicker))
-   Refactor windows module in `Local` ([#&#8203;992](chronotope/chrono#992), thanks to [@&#8203;nekevss](https://github.com/nekevss))
-   Simplify from_timestamp_millis, from_timestamp_micros ([#&#8203;1032](chronotope/chrono#1032), thanks to [@&#8203;pitdicker](https://github.com/pitdicker))
-   Backport [#&#8203;983](chronotope/chrono#983) and [#&#8203;1000](chronotope/chrono#1000) ([#&#8203;1063](chronotope/chrono#1063), thanks to [@&#8203;pitdicker](https://github.com/pitdicker))

##### Documentation

-   Backport documentation improvements ([#&#8203;1066](chronotope/chrono#1066), thanks to [@&#8203;pitdicker](https://github.com/pitdicker))
-   Add documentation for %Z quirk ([#&#8203;1051](chronotope/chrono#1051), thanks to [@&#8203;campbellcole](https://github.com/campbellcole))
-   Add an example to Weekday ([#&#8203;1019](chronotope/chrono#1019), thanks to [@&#8203;pitdicker](https://github.com/pitdicker))

##### Internal improvements

-   Gate test on `clock` feature ([#&#8203;1061](chronotope/chrono#1061), thanks to [@&#8203;pitdicker](https://github.com/pitdicker))
-   CI: Also run tests with `--no-default-features` ([#&#8203;1059](chronotope/chrono#1059), thanks to [@&#8203;pitdicker](https://github.com/pitdicker))
-   Prevent `bench_year_flags_from_year` from being optimized out ([#&#8203;1034](chronotope/chrono#1034), thanks to [@&#8203;pitdicker](https://github.com/pitdicker))
-   Fix test_leap_second during DST transition ([#&#8203;1064](chronotope/chrono#1064), thanks to [@&#8203;pitdicker](https://github.com/pitdicker))
-   Fix warnings when running tests on Windows ([#&#8203;1038](chronotope/chrono#1038), thanks to [@&#8203;pitdicker](https://github.com/pitdicker))
-   Fix tests on AIX ([#&#8203;1028](chronotope/chrono#1028), thanks to [@&#8203;ecnelises](https://github.com/ecnelises))
-   Fix doctest warnings, remove mention of deprecated methods from main doc ([#&#8203;1081](chronotope/chrono#1081), thanks to [@&#8203;pitdicker](https://github.com/pitdicker))
-   Reformat `test_datetime_parse_from_str` ([#&#8203;1078](chronotope/chrono#1078), thanks to [@&#8203;pitdicker](https://github.com/pitdicker))
-   GitHub yml shell `set -eux`, use bash ([#&#8203;1103](chronotope/chrono#1103), thanks to [@&#8203;jtmoon79](https://github.com/jtmoon79))
-   test: explicitly set `LANG` to `c` in gnu `date` ([#&#8203;1089](chronotope/chrono#1089), thanks to [@&#8203;scarf005](https://github.com/scarf005))
-   Switch test to `TryFrom` ([#&#8203;1086](chronotope/chrono#1086), thanks to [@&#8203;pitdicker](https://github.com/pitdicker))
-   Add test for issue 551 ([#&#8203;1020](chronotope/chrono#1020), thanks to [@&#8203;pitdicker](https://github.com/pitdicker))
-   RFC 2822 single-letter obsolete tests ([#&#8203;1014](chronotope/chrono#1014), thanks to [@&#8203;jtmoon79](https://github.com/jtmoon79))
-   \[CI] Lint Windows target and documentation links ([#&#8203;1062](chronotope/chrono#1062), thanks to [@&#8203;pitdicker](https://github.com/pitdicker))
-   add test_issue\_866 ([#&#8203;1077](chronotope/chrono#1077), thanks to [@&#8203;jtmoon79](https://github.com/jtmoon79))
-   Remove AUTHORS metadata ([#&#8203;1074](chronotope/chrono#1074))

On behalf of [@&#8203;djc](https://github.com/djc) and [@&#8203;esheppa](https://github.com/esheppa), thanks to all contributors!

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNS4xMDUuMSIsInVwZGF0ZWRJblZlciI6IjM1LjExNS4yIiwidGFyZ2V0QnJhbmNoIjoiZGV2ZWxvcCJ9-->

Co-authored-by: cabr2-bot <cabr2.help@gmail.com>
Reviewed-on: https://codeberg.org/Calciumdibromid/CaBr2/pulls/1909
Reviewed-by: crapStone <crapstone@noreply.codeberg.org>
Co-authored-by: Calciumdibromid Bot <cabr2_bot@noreply.codeberg.org>
Co-committed-by: Calciumdibromid Bot <cabr2_bot@noreply.codeberg.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants