I have worked extensively with times. By time, I mean the software representation of time and the mapping of various concepts surrounding this tangible entity.
Handling of Time Zone, Daylight Saving Time (DST) is a pretty important use case in most softwares. All programming languages have libraries specifically designed to manipulate time easily. However, the implementation of these APIs isn't standardized and therefore developers have to go through a learning curve in order to use these APIs effectively and correctly. But the fact is that most of the developers take the concept for granted and are contend to directly use the libraries without learning the concepts properly.
Web is full of these resources and help can be found for learning the concepts and correctly utilizing the APIs in different languages.
There's one small use case in Java for which I couldn't find any assistance and that simply is: retrieving DST details for a particular Time Zone in Java.
The java.util.TimeZone does contain DST information, however it is not exposed in a direct manner in any of the TimeZone related classes. Internally, TimeZone calculates DST in SimpleTimeZone class (an implementation of TimeZone), which is accessed within TimeZone via ZoneInfo class' static methods.
Look here for the DST related private members of java.util.SimpleTimeZone.
Fortunately, these fields are visible through the toString() method of this class. Have a look at the source.
For convenience I'm providing a simple listing to extract out the DST information of a particular TimeZone:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36 | /**
* DST details for the time zone i.e. when DST is applied and when it ends.
* @return
*/
public static String getDSTDetails(TimeZone timeZone) {
if (timeZone.getDSTSavings() > 0) {
/* Java's TimeZone related classes compute the start and end date of DST application but
* do not expose it. The only way is to decipher the toString method which fortunately
* prints enough information for us to deduce our required data.
*/
Pattern pattern = Pattern.compile("startMonth=(\\d+),startDay=(\\d+),.+endMonth=(\\d+),endDay=(\\d+),");
Matcher m = pattern.matcher(timeZone.toString());
if (m.find()) {
Calendar startCal = Calendar.getInstance();
Calendar endCal = Calendar.getInstance();
startCal.set(Calendar.MONTH, Integer.valueOf(m.group(1)));
startCal.set(Calendar.DAY_OF_MONTH, Integer.valueOf(m.group(2)));
endCal.set(Calendar.MONTH, Integer.valueOf(m.group(3)));
endCal.set(Calendar.DAY_OF_MONTH, Integer.valueOf(m.group(4)));
final SimpleDateFormat monthFormatter = new SimpleDateFormat("MMMM");
return new MessageFormat("Daylight savings starts at day {0} of {1}, ends at day {2} of {3}")
.format(new Serializable[] {
startCal.get(Calendar.DAY_OF_MONTH), monthFormatter.format(startCal.getTime()),
endCal.get(Calendar.DAY_OF_MONTH), monthFormatter.format(endCal.getTime())
}
);
}
}
return "NA";
}
|
Complete source code is also available as a Github gist.
Feel free to contact me for queries regarding time handling in Java (and on a side note, Teradata).