/
TzHelper.java
132 lines (119 loc) · 5.05 KB
/
TzHelper.java
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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/*
* TzHelper.java Feb 21, 2014
*
* Copyright (c) 2014 1&1 Internet AG. All rights reserved.
*
* $Id$
*/
package net.fortuna.ical4j.transform.rfc5545;
import net.fortuna.ical4j.model.DefaultTimeZoneRegistryFactory;
import net.fortuna.ical4j.model.Parameter;
import net.fortuna.ical4j.model.Property;
import net.fortuna.ical4j.model.TimeZoneRegistry;
import net.fortuna.ical4j.model.parameter.TzId;
import net.fortuna.ical4j.model.property.DateProperty;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.time.format.DateTimeParseException;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
/**
*
* @author corneliu dobrota
* @author daniel grigore
*
*/
class TzHelper {
private static final String MS_TIMEZONES_FILE = "msTimezones";
private static final Map<String, String> MS_TIMEZONE_IDS = new HashMap<String, String>();
private static final Map<String, String> MS_TIMEZONE_NAMES = new HashMap<String, String>();
private static final TimeZoneRegistry TIMEZONE_REGISTRY = DefaultTimeZoneRegistryFactory.getInstance()
.createRegistry();
private static final Logger LOG = LoggerFactory.getLogger(TzHelper.class);
static {
initMsTimezones();
}
private static void initMsTimezones() {
try (Scanner scanner = new Scanner(TzHelper.class.getResourceAsStream(MS_TIMEZONES_FILE))) {
while (scanner.hasNext()) {
String[] arr = scanner.nextLine().split("=");
String standardTzId = arr[1];
String displayNameAndMsTzId[] = arr[0].split(";");
MS_TIMEZONE_NAMES.put(displayNameAndMsTzId[0], standardTzId);
MS_TIMEZONE_IDS.put(displayNameAndMsTzId[1], standardTzId);
}
} catch (RuntimeException e) { // avoid NoClassDefFoundError
LOG.error("Could not load MS timezones", e);
throw new RuntimeException("Unable to load resource file " + MS_TIMEZONES_FILE, e);
}
}
static void correctTzParameterFrom(Property property) {
if (property.getParameter(Parameter.TZID) != null) {
String newTimezoneId = getCorrectedTimezoneFromTzParameter(property);
correctTzParameter(property, newTimezoneId);
}
}
static void correctTzParameterFrom(DateProperty property) {
if (property.getValue() != null && property.getValue().endsWith("Z")) {
property.getParameters().removeAll(Parameter.TZID);
return;
}
if (property.getParameter(Parameter.TZID) != null) {
String newTimezone = getCorrectedTimezoneFromTzParameter(property);
String value = property.getValue();
correctTzParameter(property, newTimezone);
if (newTimezone != null) {
property.setTimeZone(TIMEZONE_REGISTRY.getTimeZone(newTimezone));
try {
property.setValue(value);
} catch (DateTimeParseException e) {
LOG.warn("Failed to reset property value", e);
}
} else {
property.setUtc(true);
}
}
}
private static void correctTzParameter(Property property, String newTimezoneId) {
property.getParameters().removeAll(Parameter.TZID);
if (newTimezoneId != null) {
property.getParameters().add(new TzId(newTimezoneId));
}
}
private static String getCorrectedTimezoneFromTzParameter(Property property) {
String tzIdValue = property.getParameter(Parameter.TZID).getValue();
return getCorrectedTimeZoneIdFrom(tzIdValue);
}
static void correctTzValueOf(net.fortuna.ical4j.model.property.TzId tzProperty) {
String validTimezone = getCorrectedTimeZoneIdFrom(tzProperty.getValue());
if (validTimezone != null) {
tzProperty.setValue(validTimezone);
}
}
/**
* Gets a valid timezoneId for the specified timezoneValue or <code>null</code> in case the specified time zone
* value does not match anything known.
*
* @param value
* time zone value read from ICS file. The value can be a Microsoft time zone id or an invalid time zone
* value
* @return a valid timezoneId for the specified timezoneValue or <code>null</code> in case the specified time zone
* value does not match anything known
*/
private static String getCorrectedTimeZoneIdFrom(String value) {
if (value != null) {
value = value.contains("\"") ? value.replaceAll("\"", "") : value;
if (TIMEZONE_REGISTRY.getTimeZone(value) != null) {
return TIMEZONE_REGISTRY.getTimeZone(value).getID();
}
String nameCandidate = MS_TIMEZONE_NAMES.get(value);
if (nameCandidate != null) {
return TIMEZONE_REGISTRY.getTimeZone(nameCandidate) != null
? TIMEZONE_REGISTRY.getTimeZone(nameCandidate).getID() : nameCandidate;
}
return MS_TIMEZONE_IDS.get(value);
}
return null;
}
}