@@ -56,7 +56,7 @@ isolated function testUtcFromStringWithInvalidFormat() {
56
56
Utc | Error err = utcFromString (" 2007-12-0310:15:30.00Z" );
57
57
test : assertTrue (err is Error );
58
58
test : assertEquals ((< Error > err ).message (),
59
- " The provided string '2007-12-0310:15:30.00Z' does not adhere to the expected RFC 3339 format 'YYYY-MM-DDTHH:MM:SS.SSZ'. " );
59
+ " The provided string '2007-12-0310:15:30.00Z' does not adhere to the expected RFC 3339 format 'YYYY-MM-DDTHH:MM:SS.SSZ'. " );
60
60
}
61
61
62
62
@test :Config {}
@@ -668,7 +668,7 @@ isolated function testGmtToEmailStringConversion() returns Error? {
668
668
Utc utc = check utcFromString (" 2007-12-03T10:15:30.00Z" );
669
669
Utc utc2 = check utcFromString (" 2007-12-03T10:15:30.00+05:30" );
670
670
Civil civil = check civilFromString (" 2007-12-03T10:15:30.00+00:00" );
671
-
671
+
672
672
test : assertEquals (utcToEmailString (utc , " Z" ), " Mon, 3 Dec 2007 10:15:30 Z" );
673
673
test : assertEquals (utcToEmailString (utc2 , " 0" ), " Mon, 3 Dec 2007 04:45:30 +0000" );
674
674
test : assertEquals (utcToEmailString (utc ), " Mon, 3 Dec 2007 10:15:30 +0000" );
@@ -709,7 +709,6 @@ isolated function testCivilToStringWithEmptyTimeOffset() returns Error? {
709
709
710
710
@test :Config {enable : true }
711
711
isolated function testUtcFromCivilWithEmptyTimeOffsetNegative() returns Error ? {
712
- Utc expectedUtc = check utcFromString (" 2021-04-12T23:20:50.520Z" );
713
712
Civil civil = {
714
713
year : 2021 ,
715
714
month : 4 ,
@@ -728,7 +727,6 @@ isolated function testUtcFromCivilWithEmptyTimeOffsetNegative() returns Error? {
728
727
}
729
728
730
729
isolated function testUtcFromCivilWithEmptyTimeOffsetAndAbbreviation() returns Error ? {
731
- Utc expectedUtc = check utcFromString (" 2021-04-12T23:20:50.520Z" );
732
730
Civil civil = {
733
731
year : 2021 ,
734
732
month : 4 ,
@@ -760,7 +758,7 @@ isolated function testCivilToStringWithEmptyTimeOffsetAndAbbreviation() returns
760
758
test : assertEquals (civilString .message (), " the civil value should have either `utcOffset` or `timeAbbrev`" );
761
759
} else {
762
760
test : assertFail (" civilString should be error" );
763
- }
761
+ }
764
762
}
765
763
766
764
@test :Config {enable : true }
@@ -769,4 +767,120 @@ isolated function testRepeatedUtcToCivilConversion() returns Error? {
769
767
Civil civil = utcToCivil (utc );
770
768
Utc utc2 = check utcFromCivil (civil );
771
769
test : assertEquals (utc , utc2 );
772
- }
770
+ }
771
+
772
+ @test :Config {
773
+ groups : [" duration" ],
774
+ dataProvider : dataProviderCivilAddDuration
775
+ }
776
+ isolated function testCivilAddDuration(string civilString , Duration duration , string expectedResult ) returns Error ? {
777
+ Civil actualResult = check civilAddDuration (check civilFromString (civilString ), duration );
778
+ test : assertEquals (civilToString (actualResult ), expectedResult );
779
+ }
780
+
781
+ isolated function dataProviderCivilAddDuration() returns [string , Duration , string ][] {
782
+ return [
783
+ [" 2025-06-02T10:30:00Z" , {years : -1 , months : -8 , days : -5 , hours : -3 , minutes : -5 , seconds : -6 }, " 2023-09-27T07:24:54Z" ],
784
+ [" 2024-02-27T22:30:30.00+02:00" , {years : 0 , months : 0 , days : 3 , hours : 1 , minutes : 29 , seconds : 30 }, " 2024-03-02T00:00+02:00" ],
785
+ [" 1972-12-31T23:59:59+05:30" , {years : 0 , months : 15 , days : 30 , hours : 0 , minutes : 0 , seconds : 1 }, " 1974-05-01T00:00+05:30" ],
786
+ [" 2025-05-22T08:30:04.67Z" , {years : -1 , months : 4 , days : 0 , hours : -23 , minutes : 5 , seconds : -1 }, " 2024-09-21T09:35:03.670Z" ]
787
+ ];
788
+ }
789
+
790
+ @test :Config {
791
+ groups : [" duration" , " zone" ],
792
+ dataProvider : dataProviderZoneDateTimeCivilAddDuration
793
+ }
794
+ isolated function testZoneDataTimeCivilAddDuration(string zone , string civilString , Duration duration , string expectedResult ) returns Error ? {
795
+ Zone ? systemZone = getZone (zone );
796
+ test : assertTrue (systemZone is Zone );
797
+ Civil civil = check (< Zone > systemZone ).civilAddDuration (check civilFromString (civilString ), duration );
798
+ test : assertEquals (civilToString (civil ), expectedResult );
799
+ }
800
+
801
+ isolated function dataProviderZoneDateTimeCivilAddDuration() returns [string , string , Duration , string ][] {
802
+ return [
803
+ [" Asia/Colombo" , " 2025-06-02T10:30:00+05:30" , {years : -1 , months : -8 , days : -5 , hours : -3 , minutes : -5 , seconds : -6 }, " 2023-09-27T07:24:54+05:30[Asia/Colombo]" ],
804
+ [" Greenwich" , " 2025-06-02T10:30:00+05:30" , {years : -1 , months : -8 , days : -5 , hours : -3 , minutes : -5 , seconds : -6 }, " 2023-09-27T01:54:54Z[Greenwich]" ],
805
+ [" Etc/GMT-9" , " 2025-06-02T10:30:00+05:30" , {years : -1 , months : -8 , days : -5 , hours : -3 , minutes : -5 , seconds : -6 }, " 2023-09-27T10:54:54+09:00[Etc/GMT-9]" ],
806
+ [" Asia/Colombo" , " 2024-02-27T22:30:30.00+02:00" , {years : 0 , months : 0 , days : 3 , hours : 1 , minutes : 29 , seconds : 30 }, " 2024-03-02T03:30+05:30[Asia/Colombo]" ],
807
+ [" Asia/Tokyo" , " 2025-05-22T08:30:04.67Z" , {years : 1 , months : -4 , days : 3 , hours : 25 , minutes : -5 , seconds : 111 }, " 2026-01-26T18:26:55.670+09:00[Asia/Tokyo]" ],
808
+ [" Asia/Colombo" , " 2025-05-22T08:30:04.67Z" , {years : 1 , months : -12 , days : 1 , hours : -24 , minutes : 1 , seconds : -60 }, " 2025-05-22T14:00:04.670+05:30[Asia/Colombo]" ]
809
+ ];
810
+ }
811
+
812
+ @test :Config {
813
+ groups : [" duration" ],
814
+ dataProvider : dataProviderCivilRecordAddDuration
815
+ }
816
+ isolated function testCivilRecordAddDuration(Civil civilString , Duration duration , string expectedResult ) returns Error ? {
817
+ Civil actualResult = check civilAddDuration (civilString , duration );
818
+ test : assertEquals (civilToString (actualResult ), expectedResult );
819
+ }
820
+
821
+ isolated function dataProviderCivilRecordAddDuration() returns [Civil , Duration , string ][] {
822
+ return [
823
+ [{year : 2021 , month : 4 , day : 12 , hour : 23 , minute : 20 , second : 50.52 , timeAbbrev : " Z" }, {years : -100 , months : -8 , days : -5 , hours : 22 , minutes : 5 , seconds : -6 }, " 1920-08-08T21:25:44.520Z" ],
824
+ [{year : 2025 , month : 4 , day : 23 , hour : 0 , minute : 20 , second : 1.2 , timeAbbrev : " Asia/Colombo" }, {years : 5 , months : 0 , days : 0 , hours : 3 , minutes : 8 , seconds : 34 }, " 2030-04-23T03:28:35.200+05:30[Asia/Colombo]" ],
825
+ [{year : 2025 , month : 4 , day : 23 , hour : 0 , minute : 20 , second : 1.2 , utcOffset : {hours : 8 , minutes : 0 }}, {years : 0 , months : 10 , days : 5 , hours : 0 , minutes : 0 , seconds : 0 }, " 2026-02-28T00:20:01.200+08:00" ],
826
+ [{year : 2025 , month : 4 , day : 23 , hour : 0 , minute : 20 , second : 1.2 , timeAbbrev : " America/Los_Angeles" , utcOffset : {hours : 8 , minutes : 0 }}, {years : 0 , months : 10 , days : 5 , hours : 0 , minutes : 0 , seconds : 0 }, " 2026-02-28T00:20:01.200+08:00" ]
827
+ ];
828
+ }
829
+
830
+ @test :Config {
831
+ groups : [" duration" , " zone" ],
832
+ dataProvider : dataProviderZoneDateTimeCivilRecordAddDuration
833
+ }
834
+ isolated function testZoneDataTimeCivilRecordAddDuration(string zone , Civil civil , Duration duration , string expectedResult ) returns Error ? {
835
+ Zone ? systemZone = getZone (zone );
836
+ test : assertTrue (systemZone is Zone );
837
+ Civil result = check (< Zone > systemZone ).civilAddDuration (civil , duration );
838
+ test : assertEquals (civilToString (result ), expectedResult );
839
+ }
840
+
841
+ isolated function dataProviderZoneDateTimeCivilRecordAddDuration() returns [string , Civil , Duration , string ][] {
842
+ return [
843
+ [" Asia/Colombo" , {year : 2021 , month : 4 , day : 12 , hour : 23 , minute : 20 , second : 50.52 , timeAbbrev : " Z" }, {years : -11 , months : -8 , days : -30 , hours : 22 , minutes : 5 , seconds : -6 }, " 2009-07-15T02:55:44.520+05:30[Asia/Colombo]" ],
844
+ [" Z" , {year : 2025 , month : 4 , day : 23 , hour : 0 , minute : 20 , second : 1.2 , timeAbbrev : " Asia/Colombo" }, {years : 4 , months : 7 , days : 9 , hours : 3 , minutes : 8 , seconds : 34 }, " 2029-12-01T21:58:35.200Z" ],
845
+ [" America/Los_Angeles" , {year : 2030 , month : 4 , day : 23 , hour : 0 , minute : 20 , second : 1.2 , utcOffset : {hours : 8 , minutes : 0 }}, {years : 3 , months : 10 , days : 5 , hours : 0 , minutes : 0 , seconds : 55.5 }, " 2034-02-27T09:20:56.700-08:00[America/Los_Angeles]" ],
846
+ [" America/Los_Angeles" , {year : 2011 , month : 4 , day : 23 , hour : 0 , minute : 20 , second : 1.2 , timeAbbrev : " America/Los_Angeles" , utcOffset : {hours : 8 , minutes : 0 }}, {years : 0 , months : 10 , days : 6 , hours : 0 , minutes : 0 , seconds : 9.34 }, " 2012-02-28T09:20:10.540-08:00[America/Los_Angeles]" ]
847
+ ];
848
+ }
849
+
850
+ @test :Config {
851
+ groups : [" duration" ],
852
+ dataProvider : dataProviderInvalidCivilAddDuration
853
+ }
854
+ isolated function testInvalidCivilAddDuration(Civil civil , Duration duration , string errorMsg ) returns Error ? {
855
+ Civil | Error actualResult = civilAddDuration (civil , duration );
856
+ test : assertTrue (actualResult is Error );
857
+ test : assertEquals ((< Error > actualResult ).message (), errorMsg );
858
+ }
859
+
860
+ isolated function dataProviderInvalidCivilAddDuration() returns [Civil , Duration , string ][] {
861
+ return [
862
+ [{year : 2021 , month : 4 , day : 12 , hour : 23 , minute : 20 , second : 50.52 }, {years : -25 , months : 0 , days : 0 , hours : 0 , minutes : 0 , seconds : 0 }, " The civil value should have either `utcOffset` or `timeAbbrev`" ],
863
+ [{year : 2021 , month : 4 , day : 12 , hour : 23 , minute : 20 , second : 50.52 , timeAbbrev : " Colombo" }, {years : -25 , months : 0 , days : 0 , hours : 0 , minutes : 0 , seconds : 0 }, " Unknown time-zone ID: Colombo" ],
864
+ [{year : 2025 , month : 13 , day : 23 , hour : 0 , minute : 20 , second : 1.2 , timeAbbrev : " America/Los_Angeles" , utcOffset : {hours : 8 , minutes : 0 }}, {years : 0 , months : 10 , days : 5 , hours : 0 , minutes : 0 , seconds : 0 }, " Invalid value for MonthOfYear (valid values 1 - 12): 13" ]
865
+ ];
866
+ }
867
+
868
+ @test :Config {
869
+ groups : [" duration" , " zone" ],
870
+ dataProvider : dataProviderInvalidZoneDateTimeCivilAddDuration
871
+ }
872
+ isolated function testInvalidZoneDataTimeCivilAddDuration(string zone , Civil civil , Duration duration , string errorMsg ) returns Error ? {
873
+ Zone ? systemZone = getZone (zone );
874
+ test : assertTrue (systemZone is Zone );
875
+ Civil | Error result = (< Zone > systemZone ).civilAddDuration (civil , duration );
876
+ test : assertTrue (result is Error );
877
+ test : assertEquals ((< Error > result ).message (), errorMsg );
878
+ }
879
+
880
+ isolated function dataProviderInvalidZoneDateTimeCivilAddDuration() returns [string , Civil , Duration , string ][] {
881
+ return [
882
+ [" Asia/Colombo" , {year : 2021 , month : 4 , day : 12 , hour : 23 , minute : 20 , second : 50.52 , timeAbbrev : " Colombo" }, {years : -1 , months : -8 , days : -5 , hours : -3 , minutes : -5 , seconds : -6 }, " Unknown time-zone ID: Colombo" ],
883
+ [" Asia/Colombo" , {year : 2021 , month : 4 , day : 12 , hour : 23 , minute : 20 , second : 50.52 }, {years : -25 , months : 0 , days : 0 , hours : 0 , minutes : 0 , seconds : 0 }, " The civil value should have either `utcOffset` or `timeAbbrev`" ],
884
+ [" Asia/Colombo" , {year : 2025 , month : 13 , day : 23 , hour : 0 , minute : 20 , second : 1.2 , timeAbbrev : " America/Los_Angeles" , utcOffset : {hours : 8 , minutes : 0 }}, {years : 0 , months : 10 , days : 5 , hours : 0 , minutes : 0 , seconds : 0 }, " Invalid value for MonthOfYear (valid values 1 - 12): 13" ]
885
+ ];
886
+ }
0 commit comments