|
447 | 447 | end |
448 | 448 | end |
449 | 449 |
|
| 450 | +@testitem "DateTime64 to Date/DateTime" begin |
| 451 | + using Dates |
| 452 | + using PythonCall: NumpyDates |
| 453 | + |
| 454 | + # Cases: (value, unit_symbol_or_tuple, expected_DateTime, expected_Date) |
| 455 | + cases = [ |
| 456 | + # Day counts (since 1970-01-01) |
| 457 | + (10_956, :D, DateTime(1999, 12, 31, 0, 0, 0), Date(1999, 12, 31)), |
| 458 | + (0, :D, DateTime(1970, 1, 1, 0, 0, 0), Date(1970, 1, 1)), |
| 459 | + (1, :D, DateTime(1970, 1, 2, 0, 0, 0), Date(1970, 1, 2)), |
| 460 | + |
| 461 | + # Seconds since epoch |
| 462 | + (946_684_799, :s, DateTime(1999, 12, 31, 23, 59, 59), Date(1999, 12, 31)), |
| 463 | + (0, :s, DateTime(1970, 1, 1, 0, 0, 0), Date(1970, 1, 1)), |
| 464 | + (3_600, :s, DateTime(1970, 1, 1, 1, 0, 0), Date(1970, 1, 1)), |
| 465 | + |
| 466 | + # Hours/minutes (epoch-based) |
| 467 | + (24, :h, DateTime(1970, 1, 2, 0, 0, 0), Date(1970, 1, 2)), |
| 468 | + (60, :m, DateTime(1970, 1, 1, 1, 0, 0), Date(1970, 1, 1)), |
| 469 | + |
| 470 | + # Years/months (calendar truncation semantics from 1970-01-01) |
| 471 | + (30, :Y, DateTime(2000, 1, 1, 0, 0, 0), Date(2000, 1, 1)), |
| 472 | + (361, :M, DateTime(2000, 2, 1, 0, 0, 0), Date(2000, 2, 1)), |
| 473 | + (359, :M, DateTime(1999, 12, 1, 0, 0, 0), Date(1999, 12, 1)), |
| 474 | + |
| 475 | + # Weeks |
| 476 | + (1, :W, DateTime(1970, 1, 8, 0, 0, 0), Date(1970, 1, 8)), |
| 477 | + (-1, :W, DateTime(1969, 12, 25, 0, 0, 0), Date(1969, 12, 25)), |
| 478 | + |
| 479 | + # Sub-nanosecond units: floored to nanoseconds |
| 480 | + (1_500, :ps, DateTime(1970, 1, 1, 0, 0, 0) + Nanosecond(1), Date(1970, 1, 1)), |
| 481 | + (1_500_000, :fs, DateTime(1970, 1, 1, 0, 0, 0) + Nanosecond(1), Date(1970, 1, 1)), |
| 482 | + ( |
| 483 | + 1_500_000_000, |
| 484 | + :as, |
| 485 | + DateTime(1970, 1, 1, 0, 0, 0) + Nanosecond(1), |
| 486 | + Date(1970, 1, 1), |
| 487 | + ), |
| 488 | + |
| 489 | + # Multiplier tuple unit: value * multiplier is applied before adding |
| 490 | + (1_800, (:s, 2), DateTime(1970, 1, 1, 1, 0, 0), Date(1970, 1, 1)), |
| 491 | + ] |
| 492 | + |
| 493 | + @testset "$v $u" for (v, u, expdt, expd) in cases |
| 494 | + # 1) DateTime64(value, unit) |
| 495 | + x = NumpyDates.DateTime64(v, u) |
| 496 | + @test Dates.DateTime(x) == expdt |
| 497 | + @test Dates.Date(x) == expd |
| 498 | + |
| 499 | + # 2) InlineDateTime64 typed |
| 500 | + Uconst = u isa Tuple ? (NumpyDates.Unit(u[1]), Int(u[2])) : NumpyDates.Unit(u) |
| 501 | + y = NumpyDates.InlineDateTime64{Uconst}(v) |
| 502 | + @test Dates.DateTime(y) == expdt |
| 503 | + @test Dates.Date(y) == expd |
| 504 | + |
| 505 | + # 3) InlineDateTime64 dynamic |
| 506 | + z = NumpyDates.InlineDateTime64(v, u) |
| 507 | + @test Dates.DateTime(z) == expdt |
| 508 | + @test Dates.Date(z) == expd |
| 509 | + end |
| 510 | + |
| 511 | + # NaT conversion errors |
| 512 | + for u in (:Y, :M, :W, :D, :h, :m, :s, :ms, :us, :ns, :ps, :fs, :as) |
| 513 | + nat1 = NumpyDates.DateTime64("NaT", u) |
| 514 | + @test_throws Exception Dates.DateTime(nat1) |
| 515 | + @test_throws Exception Dates.Date(nat1) |
| 516 | + |
| 517 | + Uconst = NumpyDates.Unit(u) |
| 518 | + nat2 = NumpyDates.InlineDateTime64{Uconst}("NaT") |
| 519 | + @test_throws Exception Dates.DateTime(nat2) |
| 520 | + @test_throws Exception Dates.Date(nat2) |
| 521 | + |
| 522 | + nat3 = NumpyDates.InlineDateTime64("NaT", u) |
| 523 | + @test_throws Exception Dates.DateTime(nat3) |
| 524 | + @test_throws Exception Dates.Date(nat3) |
| 525 | + end |
| 526 | +end |
| 527 | + |
450 | 528 | @testitem "TimeDelta64 from Dates.Period" begin |
451 | 529 | using Dates |
452 | 530 | using PythonCall: NumpyDates |
|
517 | 595 | end |
518 | 596 | end |
519 | 597 |
|
520 | | -@testitem "TimeDelta64 from String (NaT only)" begin |
| 598 | +@testitem "TimeDelta64 from String" begin |
521 | 599 | using Dates |
522 | 600 | using PythonCall: NumpyDates |
523 | 601 |
|
|
670 | 748 | end |
671 | 749 | end |
672 | 750 |
|
673 | | -@testitem "DateTime64 to Date/DateTime" begin |
674 | | - using Dates |
675 | | - using PythonCall: NumpyDates |
676 | | - |
677 | | - # Cases: (value, unit_symbol_or_tuple, expected_DateTime, expected_Date) |
678 | | - cases = [ |
679 | | - # Day counts (since 1970-01-01) |
680 | | - (10_956, :D, DateTime(1999, 12, 31, 0, 0, 0), Date(1999, 12, 31)), |
681 | | - (0, :D, DateTime(1970, 1, 1, 0, 0, 0), Date(1970, 1, 1)), |
682 | | - (1, :D, DateTime(1970, 1, 2, 0, 0, 0), Date(1970, 1, 2)), |
683 | | - |
684 | | - # Seconds since epoch |
685 | | - (946_684_799, :s, DateTime(1999, 12, 31, 23, 59, 59), Date(1999, 12, 31)), |
686 | | - (0, :s, DateTime(1970, 1, 1, 0, 0, 0), Date(1970, 1, 1)), |
687 | | - (3_600, :s, DateTime(1970, 1, 1, 1, 0, 0), Date(1970, 1, 1)), |
688 | | - |
689 | | - # Hours/minutes (epoch-based) |
690 | | - (24, :h, DateTime(1970, 1, 2, 0, 0, 0), Date(1970, 1, 2)), |
691 | | - (60, :m, DateTime(1970, 1, 1, 1, 0, 0), Date(1970, 1, 1)), |
692 | | - |
693 | | - # Years/months (calendar truncation semantics from 1970-01-01) |
694 | | - (30, :Y, DateTime(2000, 1, 1, 0, 0, 0), Date(2000, 1, 1)), |
695 | | - (361, :M, DateTime(2000, 2, 1, 0, 0, 0), Date(2000, 2, 1)), |
696 | | - (359, :M, DateTime(1999, 12, 1, 0, 0, 0), Date(1999, 12, 1)), |
697 | | - |
698 | | - # Weeks |
699 | | - (1, :W, DateTime(1970, 1, 8, 0, 0, 0), Date(1970, 1, 8)), |
700 | | - (-1, :W, DateTime(1969, 12, 25, 0, 0, 0), Date(1969, 12, 25)), |
701 | | - |
702 | | - # Sub-nanosecond units: floored to nanoseconds |
703 | | - (1_500, :ps, DateTime(1970, 1, 1, 0, 0, 0) + Nanosecond(1), Date(1970, 1, 1)), |
704 | | - (1_500_000, :fs, DateTime(1970, 1, 1, 0, 0, 0) + Nanosecond(1), Date(1970, 1, 1)), |
705 | | - ( |
706 | | - 1_500_000_000, |
707 | | - :as, |
708 | | - DateTime(1970, 1, 1, 0, 0, 0) + Nanosecond(1), |
709 | | - Date(1970, 1, 1), |
710 | | - ), |
711 | | - |
712 | | - # Multiplier tuple unit: value * multiplier is applied before adding |
713 | | - (1_800, (:s, 2), DateTime(1970, 1, 1, 1, 0, 0), Date(1970, 1, 1)), |
714 | | - ] |
715 | | - |
716 | | - @testset "$v $u" for (v, u, expdt, expd) in cases |
717 | | - # 1) DateTime64(value, unit) |
718 | | - x = NumpyDates.DateTime64(v, u) |
719 | | - @test Dates.DateTime(x) == expdt |
720 | | - @test Dates.Date(x) == expd |
721 | | - |
722 | | - # 2) InlineDateTime64 typed |
723 | | - Uconst = u isa Tuple ? (NumpyDates.Unit(u[1]), Int(u[2])) : NumpyDates.Unit(u) |
724 | | - y = NumpyDates.InlineDateTime64{Uconst}(v) |
725 | | - @test Dates.DateTime(y) == expdt |
726 | | - @test Dates.Date(y) == expd |
727 | | - |
728 | | - # 3) InlineDateTime64 dynamic |
729 | | - z = NumpyDates.InlineDateTime64(v, u) |
730 | | - @test Dates.DateTime(z) == expdt |
731 | | - @test Dates.Date(z) == expd |
732 | | - end |
733 | | - |
734 | | - # NaT conversion errors |
735 | | - for u in (:Y, :M, :W, :D, :h, :m, :s, :ms, :us, :ns, :ps, :fs, :as) |
736 | | - nat1 = NumpyDates.DateTime64("NaT", u) |
737 | | - @test_throws Exception Dates.DateTime(nat1) |
738 | | - @test_throws Exception Dates.Date(nat1) |
739 | | - |
740 | | - Uconst = NumpyDates.Unit(u) |
741 | | - nat2 = NumpyDates.InlineDateTime64{Uconst}("NaT") |
742 | | - @test_throws Exception Dates.DateTime(nat2) |
743 | | - @test_throws Exception Dates.Date(nat2) |
744 | | - |
745 | | - nat3 = NumpyDates.InlineDateTime64("NaT", u) |
746 | | - @test_throws Exception Dates.DateTime(nat3) |
747 | | - @test_throws Exception Dates.Date(nat3) |
748 | | - end |
749 | | -end |
750 | | - |
751 | 751 | @testitem "defaultunit" begin |
752 | 752 | using Dates |
753 | 753 | using PythonCall: NumpyDates |
|
0 commit comments