Skip to content

Commit

Permalink
Merge pull request #487 from ayeshLK/master
Browse files Browse the repository at this point in the history
Add support to convert `time:Civil` to `string` by using the time abbreviation
  • Loading branch information
ayeshLK authored Sep 12, 2024
2 parents 75db636 + d104164 commit 6335bd3
Show file tree
Hide file tree
Showing 8 changed files with 42 additions and 55 deletions.
6 changes: 3 additions & 3 deletions ballerina/Ballerina.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
org = "ballerina"
name = "time"
version = "2.4.0"
version = "2.5.0"
authors = ["Ballerina"]
keywords = ["time", "utc", "epoch", "civil"]
repository = "https://github.com/ballerina-platform/module-ballerina-time"
Expand All @@ -15,5 +15,5 @@ graalvmCompatible = true
[[platform.java17.dependency]]
groupId = "io.ballerina.stdlib"
artifactId = "time-native"
version = "2.4.0"
path = "../native/build/libs/time-native-2.4.0.jar"
version = "2.5.0"
path = "../native/build/libs/time-native-2.5.0-SNAPSHOT.jar"
2 changes: 1 addition & 1 deletion ballerina/Dependencies.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ modules = [
[[package]]
org = "ballerina"
name = "time"
version = "2.4.0"
version = "2.5.0"
dependencies = [
{org = "ballerina", name = "jballerina.java"},
{org = "ballerina", name = "test"}
Expand Down
35 changes: 8 additions & 27 deletions ballerina/tests/time_test.bal
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,7 @@ isolated function testCivilToString() returns Error? {
utcOffset: zoneOffset
};
string civilStr = check civilToString(civil);
string expectedStr = "2021-03-04T19:03:28.839564Z";
string expectedStr = "2021-03-05T00:33:28.839564+05:30";
test:assertEquals(civilStr, expectedStr);
}

Expand All @@ -383,23 +383,23 @@ isolated function testCivilToStringWithTimeOfDay() returns Error? {
utcOffset: zoneOffset
};
string civilStr = check civilToString(civil);
string expectedStr = "2021-03-04T19:03:28.839564Z";
string expectedStr = "2021-03-05T00:33:28.839564+05:30";
test:assertEquals(civilStr, expectedStr);
}

@test:Config {}
isolated function testCivilToStringWithoutOffset() {
isolated function testCivilToStringWithTimeAbbreviation() returns Error? {
Civil civil = {
year: 2021,
month: 4,
day: 13,
hour: 4,
minute: 70,
minute: 33,
timeAbbrev: "Asia/Colombo"
};
string|Error err = civilToString(civil);
test:assertTrue(err is Error);
test:assertEquals((<Error>err).message(), "civil.utcOffset must not be null");
string civilStr = check civilToString(civil);
string expectedStr = "2021-04-13T04:33+05:30[Asia/Colombo]";
test:assertEquals(civilStr, expectedStr);
}

@test:Config {}
Expand Down Expand Up @@ -727,25 +727,6 @@ isolated function testUtcFromCivilWithEmptyTimeOffsetNegative() returns Error? {
}
}

@test:Config {enable: true}
isolated function testCivilToStringWithEmptyTimeOffsetNegative() returns Error? {
Civil civil = {
year: 2021,
month: 4,
day: 12,
hour: 23,
minute: 20,
second: 50.52,
timeAbbrev: "Asia/Colombo"
};
string|error civilString = civilToString(civil);
if civilString is error {
test:assertEquals(civilString.message(), "civil.utcOffset must not be null");
} else {
test:assertFail("civilString should be error");
}
}

isolated function testUtcFromCivilWithEmptyTimeOffsetAndAbbreviation() returns Error? {
Utc expectedUtc = check utcFromString("2021-04-12T23:20:50.520Z");
Civil civil = {
Expand Down Expand Up @@ -776,7 +757,7 @@ isolated function testCivilToStringWithEmptyTimeOffsetAndAbbreviation() returns
};
string|error civilString = civilToString(civil);
if civilString is error {
test:assertEquals(civilString.message(), "civil.utcOffset must not be null");
test:assertEquals(civilString.message(), "the civil value should have either `utcOffset` or `timeAbbrev`");
} else {
test:assertFail("civilString should be error");
}
Expand Down
37 changes: 19 additions & 18 deletions ballerina/time_apis.bal
Original file line number Diff line number Diff line change
Expand Up @@ -162,31 +162,31 @@ public isolated function civilFromString(string dateTimeString) returns Civil|Er
return check externCivilFromString(dateTimeString);
}

# Obtain a RFC 3339 timestamp (e.g., `2007-12-03T10:15:30.00Z`) from a given `time:Civil`.
# Obtain a RFC 3339 timestamp (e.g., `2021-03-05T00:33:28.839564+05:30`) from a given `time:Civil`.
# ```ballerina
# time:Civil civil = check time:civilFromString("2007-12-03T10:15:30.00Z");
# string|time:Error civilString = time:civilToString(civil);
# ```
# + civil - `time:Civil` that needs to be converted
# + return - The corresponding string value or an error if the specified `time:Civil` contains invalid parameters (e.g., `month` > 12)
public isolated function civilToString(Civil civil) returns string|Error {
ZoneOffset utcOffset;
if civil?.utcOffset is () {
if civil?.timeAbbrev !is () && string:toLowerAscii(<string>civil?.timeAbbrev) == "z" {
utcOffset = <ZoneOffset>{hours: 0, minutes: 0, seconds: 0};
} else {
return error FormatError("civil.utcOffset must not be null");
}
} else {
utcOffset = <ZoneOffset>civil?.utcOffset;
ZoneOffset? utcOffset = civil?.utcOffset;
string? timeAbbrev = civil?.timeAbbrev;

HeaderZoneHandling zoneHandling = PREFER_ZONE_OFFSET;
if utcOffset is () && timeAbbrev is () {
return error FormatError("the civil value should have either `utcOffset` or `timeAbbrev`");
} else if utcOffset is () && timeAbbrev is string {
zoneHandling = PREFER_TIME_ABBREV;
}
decimal? civilTimeSecField = civil?.second;
decimal? utcOffsetSecField = utcOffset?.seconds;
decimal civilTimeSeconds = (civilTimeSecField is Seconds) ? civilTimeSecField : 0.0;
decimal utcOffsetSeconds = (utcOffsetSecField is decimal) ? utcOffsetSecField : 0.0;

return externCivilToString(civil.year, civil.month, civil.day, civil.hour, civil.minute, civilTimeSeconds, utcOffset.
hours, utcOffset.minutes, utcOffsetSeconds);
int utcOffsetHours = utcOffset?.hours ?: 0;
int utcOffsetMinutes = utcOffset?.minutes ?: 0;
decimal utcOffsetSeconds = utcOffset?.seconds ?: 0.0;
decimal civilTimeSeconds = civil?.second ?: 0.0;

return externCivilToString(civil.year, civil.month, civil.day, civil.hour, civil.minute, civilTimeSeconds,
utcOffsetHours, utcOffsetMinutes, utcOffsetSeconds, timeAbbrev ?: "", zoneHandling);
}

# Converts a given UTC to an email formatted string (e.g `Mon, 3 Dec 2007 10:15:30 GMT`).
Expand Down Expand Up @@ -298,8 +298,9 @@ isolated function externCivilFromString(string dateTimeString) returns Civil|Err
'class: "io.ballerina.stdlib.time.nativeimpl.ExternMethods"
} external;

isolated function externCivilToString(int year, int month, int day, int hour, int minute, decimal second, int zoneHour,
int zoneMinute, decimal zoneSecond) returns string|Error = @java:Method {
isolated function externCivilToString(int year, int month, int day, int hour, int minute, decimal second,
int zoneHour, int zoneMinute, decimal zoneSecond,
string timeAbber, HeaderZoneHandling zoneHandling) returns string|Error = @java:Method {
name: "externCivilToString",
'class: "io.ballerina.stdlib.time.nativeimpl.ExternMethods"
} external;
Expand Down
5 changes: 5 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [unreleased]

### Fixed
- [When converting a `time:Civil` with time-zone information to a string using `time:civilToString` API error is thrown](https://github.com/ballerina-platform/ballerina-library/issues/6986)

## [2.3.0] - 2023-06-30
### changed
- [Mark Standard Libraries as GraalVM Compatible](https://github.com/ballerina-platform/ballerina-standard-library/issues/4568)
- [Add support for inferring utc offset for zulu time(Z) in utcFromCivil and civilToString APIs](https://github.com/ballerina-platform/module-ballerina-time/pull/459)
Expand Down
2 changes: 1 addition & 1 deletion docs/spec/spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ The time library contains several conversion APIs to convert UTC to civil. The t
```ballerina
public isolated function civilFromString(string dateTimeString) returns Civil|Error;
```
4. Civil to an RFC timestamp string
4. Civil to an RFC 3339 timestamp string (e.g., `2021-03-05T00:33:28.839564+05:30`).
```ballerina
public isolated function civilToString(Civil civil) returns string|Error;
```
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
org.gradle.caching=true
group=io.ballerina.stdlib
version=2.4.1-SNAPSHOT
version=2.5.0-SNAPSHOT
ballerinaLangVersion=2201.8.0
puppycrawlCheckstyleVersion=10.12.0
ballerinaGradlePluginVersion=2.0.1
Original file line number Diff line number Diff line change
Expand Up @@ -157,13 +157,13 @@ public static Object externCivilFromEmailString(BString dateTimeString) {
}

public static Object externCivilToString(long year, long month, long day, long hour, long minute, BDecimal second,
long zoneHour, long zoneMinute, BDecimal zoneSecond) {
long zoneHour, long zoneMinute, BDecimal zoneSecond, BString zoneAbbr,
BString zoneHandling) {

try {
ZonedDateTime dateTime = TimeValueHandler.createZoneDateTimeFromCivilValues(year, month, day, hour,
minute, second, zoneHour, zoneMinute, zoneSecond, null,
Constants.HeaderZoneHandling.PREFER_ZONE_OFFSET.toString());
return StringUtils.fromString(dateTime.toInstant().toString());
minute, second, zoneHour, zoneMinute, zoneSecond, zoneAbbr, zoneHandling.getValue());
return StringUtils.fromString(dateTime.toString());
} catch (DateTimeException e) {
return Utils.createError(Errors.FormatError, e.getMessage());
}
Expand Down

0 comments on commit 6335bd3

Please sign in to comment.