1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package davmail.util;
21
22 import davmail.exception.DavMailException;
23 import org.apache.log4j.Logger;
24
25 import java.text.ParseException;
26 import java.text.SimpleDateFormat;
27 import java.time.LocalDate;
28 import java.time.LocalDateTime;
29 import java.time.ZoneId;
30 import java.time.ZonedDateTime;
31 import java.time.format.DateTimeFormatter;
32 import java.time.format.DateTimeParseException;
33 import java.time.format.TextStyle;
34 import java.util.Locale;
35 import java.util.ResourceBundle;
36 import java.util.TimeZone;
37
38
39
40
41 public class DateUtil {
42
43 protected static final Logger LOGGER = Logger.getLogger(DateUtil.class);
44
45 public static final String GRAPH_DATE_TIME = "yyyy-MM-dd'T'HH:mm:ss";
46 public static final String GRAPH_ZULU_DATE_TIME = "yyyy-MM-dd'T'HH:mm:ss'Z'";
47
48 public static final String CALDAV_DATE_TIME = "yyyyMMdd'T'HHmmss";
49 public static final String ISO8601_DATE_TIME = "yyyy-MM-dd'T'HH:mm:ssXXX";
50
51 public static final String YYYY_MM_DDTHH_MM_SS_SSSSSSS = "yyyy-MM-dd'T'HH:mm:ss.SSSSSSS";
52
53 public static final TimeZone UTC = TimeZone.getTimeZone("UTC");
54
55
56
57
58
59 public static final ResourceBundle STD_TO_EXCHANGE_TZ = ResourceBundle.getBundle("exchtimezones");
60
61
62
63 public static final ResourceBundle EXCHANGE_TO_STD_TZ = ResourceBundle.getBundle("stdtimezones");
64
65 public static final ResourceBundle VTIMEZONES = ResourceBundle.getBundle("vtimezones");
66
67
68
69
70
71
72
73 public static String getExchangeTimeZone(String timezoneId) {
74 if (timezoneId == null) {
75 return null;
76 } else if (EXCHANGE_TO_STD_TZ.containsKey(timezoneId)) {
77 return timezoneId;
78 } else if (STD_TO_EXCHANGE_TZ.containsKey(timezoneId)) {
79 return STD_TO_EXCHANGE_TZ.getString(timezoneId);
80 } else if ("tzone://Microsoft/Utc".equals(timezoneId)) {
81 return "UTC";
82 } else if ("tzone://Microsoft/Custom".equals(timezoneId)) {
83 return null;
84 } else {
85 LOGGER.warn("Unknown timezone: " + timezoneId);
86 return null;
87 }
88 }
89
90
91
92
93
94
95 public static String getStandardTimeZone(String timezoneId) {
96 if (timezoneId == null) {
97 return null;
98 } else if (STD_TO_EXCHANGE_TZ.containsKey(timezoneId)) {
99 return timezoneId;
100 } else if (EXCHANGE_TO_STD_TZ.containsKey(timezoneId)) {
101 return EXCHANGE_TO_STD_TZ.getString(timezoneId);
102 } else if ("tzone://Microsoft/Utc".equals(timezoneId)) {
103 return "UTC";
104 } else if ("tzone://Microsoft/Custom".equals(timezoneId)) {
105 return null;
106 } else {
107 LOGGER.warn("Unknown timezone: " + timezoneId);
108 return null;
109 }
110 }
111
112 public static TimeZone getTimeZone(String timezoneId) {
113 String standardTimeZoneId = getStandardTimeZone(timezoneId);
114 if (standardTimeZoneId != null) {
115 return TimeZone.getTimeZone(standardTimeZoneId);
116 }
117 return TimeZone.getTimeZone("UTC");
118 }
119
120 public static String getVTimeZone(String timezoneId) {
121 String exchangeTimeZone = getExchangeTimeZone(timezoneId);
122 if (exchangeTimeZone != null && VTIMEZONES.containsKey(exchangeTimeZone)) {
123 return VTIMEZONES.getString(exchangeTimeZone);
124 } else {
125 LOGGER.warn("VTimezone not available for timezone: " + timezoneId);
126 return null;
127 }
128 }
129
130 public static String convertDate(String sourceDate, String sourceFormat, String sourceTimezone,
131 String targetFormat, String targetTimezone) throws DavMailException {
132 return convertDate(sourceDate, sourceFormat, getTimeZone(sourceTimezone), targetFormat, getTimeZone(targetTimezone));
133 }
134
135 public static String convertDate(String sourceDate, String sourceFormat, TimeZone sourceTimezone,
136 String targetFormat, TimeZone targetTimezone) throws DavMailException {
137 String targetDate;
138 SimpleDateFormat parser = new SimpleDateFormat(sourceFormat);
139 parser.setTimeZone(sourceTimezone);
140 SimpleDateFormat formatter = new SimpleDateFormat(targetFormat);
141 formatter.setTimeZone(targetTimezone);
142 try {
143 targetDate = formatter.format(parser.parse(sourceDate));
144 } catch (ParseException e) {
145 LOGGER.error("Error converting date: " + sourceDate + " from " + sourceFormat + " to " + targetFormat, e);
146 throw new DavMailException("EXCEPTION_INVALID_DATE", sourceDate);
147 }
148 return targetDate;
149 }
150
151 public static String convertISO8601ToZulu(String sourceDate) throws DavMailException {
152
153 String targetDate;
154
155 SimpleDateFormat parser = new SimpleDateFormat(ISO8601_DATE_TIME);
156 SimpleDateFormat formatter = new SimpleDateFormat(GRAPH_ZULU_DATE_TIME);
157 formatter.setTimeZone(UTC);
158 try {
159 targetDate = formatter.format(parser.parse(sourceDate));
160 } catch (ParseException e) {
161 LOGGER.error("Error converting date: " + sourceDate + " from " + ISO8601_DATE_TIME + " to " + GRAPH_ZULU_DATE_TIME, e);
162 throw new DavMailException("EXCEPTION_INVALID_DATE", sourceDate);
163 }
164 return targetDate;
165 }
166
167 public static String getDayOfWeek(String date) throws DavMailException {
168 if (date != null) {
169 try {
170 LocalDate localDate = LocalDate.parse(date, DateTimeFormatter.ISO_LOCAL_DATE);
171 return localDate.getDayOfWeek().getDisplayName(TextStyle.FULL, Locale.ENGLISH).toLowerCase();
172 } catch (DateTimeParseException e) {
173 throw new DavMailException("EXCEPTION_INVALID_DATE", date);
174 }
175 }
176 return null;
177 }
178
179 public static String convertDateFormat(String sourceDate, String sourceFormat, String targetFormat) throws DavMailException {
180 String targetDate = null;
181 if (sourceDate != null) {
182 try {
183 DateTimeFormatter parser = DateTimeFormatter.ofPattern(sourceFormat);
184 DateTimeFormatter formatter = DateTimeFormatter.ofPattern(targetFormat);
185 LocalDateTime localDateTime = LocalDateTime.parse(sourceDate, parser);
186
187 targetDate = localDateTime.format(formatter);
188 } catch (DateTimeParseException e) {
189 throw new DavMailException("EXCEPTION_INVALID_DATE", sourceDate);
190 }
191 }
192 return targetDate;
193 }
194
195 public static String convertToUTCDateFormat(String sourceDate, String sourceTimezone, String sourceFormat, String targetFormat) throws DavMailException {
196 String targetDate = null;
197 if (sourceDate != null && sourceTimezone != null) {
198 try {
199 DateTimeFormatter parser = DateTimeFormatter.ofPattern(sourceFormat);
200 DateTimeFormatter formatter = DateTimeFormatter.ofPattern(targetFormat);
201 LocalDateTime localDateTime = LocalDateTime.parse(sourceDate, parser);
202
203
204 ZonedDateTime zonedStart = localDateTime.atZone(ZoneId.of(sourceTimezone));
205 ZonedDateTime utcStartDate = zonedStart.withZoneSameInstant(ZoneId.of("UTC"));
206 targetDate = utcStartDate.format(formatter);
207 } catch (DateTimeParseException e) {
208 throw new DavMailException("EXCEPTION_INVALID_DATE", sourceDate);
209 }
210 }
211 return targetDate;
212 }
213 }