Unlock a world of possibilities! Login now and discover the exclusive benefits awaiting you.
Hi could someone explain to me how i convert between timezones using Talend's built in routines?
Scenario
I am based in GMT (Talend's locale) , i have a date in Central Time (GMT-5) which i want to convert to UTC
TalendDate.formatDateInUTC seems to always use my machine's locale. How do i tell the routine that the source locale is actually CT (or any other timezone for that matter)?
Many thanks
I'm not convinced any of the TalendDate functions with a timezone behave correctly unless I'm really not understanding something so I've written my own in Java 8 based on this. posting here in case it helps someone else.
/**
* convertBetweenTimezones: converts a time string from one timezone to another.
* Use the country names listed https://docs.oracle.com/javase/8/docs/api/java/time/ZoneId.html
* or run
* System.out.println(ZoneId.getAvailableZoneIds()).
*
* 3 letter codes you can use are UTC,
* CET
* EET
* Etc/GMT+3
* Etc/GMT-6
* GB
* GMT
* MET
* NZ
* PRC
* ROK
* UCT
* UTC
* WET
*
*
* {talendTypes} String
*
*
* {Category} User Defined
*
*
* {param} string("yyyy-MM-dd HH:mm:ss") input: The date string pattern to be used.
*
* {param} stringDate("2015-01-22 10:15:55") input: The date as a string to be converted.
*
* {param} fromTimezone("Asia/Singapore") input: The original timezone of the date as either country name "Australia/Darwin" or TZ code "ACT".
*
* {param} toTimezone("America/New_York") input: The timezone to convert the date to as either country name "Australia/Darwin" or TZ code "ACT".
*
* {example} convertBetweenTimezones("yyyy-MM-dd HH:mm:ss", "2015-01-22 10:15:55", "Asia/Singapore", "America/New_York") # "2015-01-22 09:15:55".
*/
public synchronized static String convertBetweenTimezones(String pattern, String stringDate, String fromTimezone, String toTimezone) {
String convertedDate = "";
try {
//turn the string into a local date then apply the fromTimezone
LocalDateTime ldt = LocalDateTime.parse(stringDate, DateTimeFormatter.ofPattern(pattern));
ZoneId fromZoneId = ZoneId.of(fromTimezone);
//LocalDateTime + ZoneId = ZonedDateTime in source TZ
ZonedDateTime fromZonedDateTime = ldt.atZone(fromZoneId);
//convert to TZ of toTimezone
ZoneId toZoneId = ZoneId.of(toTimezone);
ZonedDateTime toDateTime = fromZonedDateTime.withZoneSameInstant(toZoneId);
DateTimeFormatter format = DateTimeFormatter.ofPattern(pattern);
convertedDate = format.format(toDateTime);
} catch (Exception e) {
throw new RuntimeException(e);
}
return convertedDate;
}
@Matt Evans
Please check https://community.talend.com/s/question/0D55b00006OYVHPCA5/how-to-keep-datetime-string-value-during-applying-the-time-zone I shared a solution to a similar problem.
Hope that helps.
Thanks but i was trying to use the built in routines if possible. looking at the source code for TalendDate.formatDateInUTC why does it apply the original timezone in the last step rather than UTC? Isn't applying the local timezone rather than UTC?
I'm not convinced any of the TalendDate functions with a timezone behave correctly unless I'm really not understanding something so I've written my own in Java 8 based on this. posting here in case it helps someone else.
/**
* convertBetweenTimezones: converts a time string from one timezone to another.
* Use the country names listed https://docs.oracle.com/javase/8/docs/api/java/time/ZoneId.html
* or run
* System.out.println(ZoneId.getAvailableZoneIds()).
*
* 3 letter codes you can use are UTC,
* CET
* EET
* Etc/GMT+3
* Etc/GMT-6
* GB
* GMT
* MET
* NZ
* PRC
* ROK
* UCT
* UTC
* WET
*
*
* {talendTypes} String
*
*
* {Category} User Defined
*
*
* {param} string("yyyy-MM-dd HH:mm:ss") input: The date string pattern to be used.
*
* {param} stringDate("2015-01-22 10:15:55") input: The date as a string to be converted.
*
* {param} fromTimezone("Asia/Singapore") input: The original timezone of the date as either country name "Australia/Darwin" or TZ code "ACT".
*
* {param} toTimezone("America/New_York") input: The timezone to convert the date to as either country name "Australia/Darwin" or TZ code "ACT".
*
* {example} convertBetweenTimezones("yyyy-MM-dd HH:mm:ss", "2015-01-22 10:15:55", "Asia/Singapore", "America/New_York") # "2015-01-22 09:15:55".
*/
public synchronized static String convertBetweenTimezones(String pattern, String stringDate, String fromTimezone, String toTimezone) {
String convertedDate = "";
try {
//turn the string into a local date then apply the fromTimezone
LocalDateTime ldt = LocalDateTime.parse(stringDate, DateTimeFormatter.ofPattern(pattern));
ZoneId fromZoneId = ZoneId.of(fromTimezone);
//LocalDateTime + ZoneId = ZonedDateTime in source TZ
ZonedDateTime fromZonedDateTime = ldt.atZone(fromZoneId);
//convert to TZ of toTimezone
ZoneId toZoneId = ZoneId.of(toTimezone);
ZonedDateTime toDateTime = fromZonedDateTime.withZoneSameInstant(toZoneId);
DateTimeFormatter format = DateTimeFormatter.ofPattern(pattern);
convertedDate = format.format(toDateTime);
} catch (Exception e) {
throw new RuntimeException(e);
}
return convertedDate;
}
Beats me why this behavior is there...