et-orbi 1.1.7 → 1.1.8

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,74 @@
1
+
2
+ module EtOrbi
3
+
4
+ class << self
5
+
6
+ def platform_info
7
+
8
+ etos = Proc.new { |k, v| "#{k}:#{v.inspect}" }
9
+
10
+ h = {
11
+ 'etz' => ENV['TZ'],
12
+ 'tnz' => Time.now.zone,
13
+ 'tziv' => tzinfo_version,
14
+ 'tzidv' => tzinfo_data_version,
15
+ 'rv' => RUBY_VERSION,
16
+ 'rp' => RUBY_PLATFORM,
17
+ 'win' => Gem.win_platform?,
18
+ 'rorv' => (Rails::VERSION::STRING rescue nil),
19
+ 'astz' => ([ Time.zone.class, Time.zone.tzinfo.name ] rescue nil),
20
+ 'eov' => EtOrbi::VERSION,
21
+ 'eotnz' => '???',
22
+ 'eotnfz' => '???',
23
+ 'eotlzn' => '???' }
24
+ if ltz = EtOrbi::EoTime.local_tzone
25
+ h['eotnz'] = EtOrbi::EoTime.now.zone
26
+ h['eotnfz'] = EtOrbi::EoTime.now.strftime('%z')
27
+ h['eotnfZ'] = EtOrbi::EoTime.now.strftime('%Z')
28
+ h['eotlzn'] = ltz.name
29
+ end
30
+
31
+ "(#{h.map(&etos).join(',')},#{gather_tzs.map(&etos).join(',')})"
32
+ end
33
+
34
+ # For `make info`
35
+ #
36
+ def _make_info
37
+
38
+ puts render_nozone_time(Time.now.to_f)
39
+ puts platform_info
40
+ end
41
+
42
+ def render_nozone_time(seconds)
43
+
44
+ t =
45
+ Time.utc(1970) + seconds
46
+ ts =
47
+ t.strftime('%Y-%m-%d %H:%M:%S') +
48
+ ".#{(seconds % 1).to_s.split('.').last}"
49
+ tz =
50
+ EtOrbi.determine_local_tzone
51
+ z =
52
+ tz ? tz.period_for_local(t).abbreviation.to_s : nil
53
+
54
+ "(secs:#{seconds},utc~:#{ts.inspect},ltz~:#{z.inspect})"
55
+ end
56
+
57
+ protected
58
+
59
+ def tzinfo_version
60
+
61
+ #TZInfo::VERSION
62
+ Gem.loaded_specs['tzinfo'].version.to_s
63
+ rescue => err
64
+ err.inspect
65
+ end
66
+
67
+ def tzinfo_data_version
68
+
69
+ #TZInfo::Data::VERSION rescue nil
70
+ Gem.loaded_specs['tzinfo-data'].version.to_s rescue nil
71
+ end
72
+ end
73
+ end
74
+
@@ -0,0 +1,112 @@
1
+
2
+ module EtOrbi
3
+
4
+ class << self
5
+
6
+ def now(zone=nil)
7
+
8
+ EoTime.new(Time.now.to_f, zone)
9
+ end
10
+
11
+ def parse(str, opts={})
12
+
13
+ str, str_zone = extract_zone(str)
14
+
15
+ if defined?(::Chronic) && t = ::Chronic.parse(str, opts)
16
+
17
+ str = [ t.strftime('%F %T'), str_zone ].compact.join(' ')
18
+ end
19
+
20
+ begin
21
+ DateTime.parse(str)
22
+ rescue
23
+ fail ArgumentError, "No time information in #{str.inspect}"
24
+ end
25
+ #end if RUBY_VERSION < '1.9.0'
26
+ #end if RUBY_VERSION < '2.0.0'
27
+ #
28
+ # is necessary since Time.parse('xxx') in Ruby < 1.9 yields `now`
29
+
30
+ zone =
31
+ opts[:zone] ||
32
+ get_tzone(str_zone) ||
33
+ determine_local_tzone
34
+
35
+ local = Time.parse(str)
36
+ secs = zone.local_to_utc(local).to_f
37
+
38
+ EoTime.new(secs, zone)
39
+ end
40
+
41
+ def make_time(*a)
42
+
43
+ zone = a.length > 1 ? get_tzone(a.last) : nil
44
+ a.pop if zone
45
+
46
+ o = a.length > 1 ? a : a.first
47
+
48
+ case o
49
+ when Time then make_from_time(o, zone)
50
+ when Date then make_from_date(o, zone)
51
+ when Array then make_from_array(o, zone)
52
+ when String then make_from_string(o, zone)
53
+ when Numeric then make_from_numeric(o, zone)
54
+ when ::EtOrbi::EoTime then make_from_eotime(o, zone)
55
+ else fail ArgumentError.new(
56
+ "Cannot turn #{o.inspect} to a ::EtOrbi::EoTime instance")
57
+ end
58
+ end
59
+ alias make make_time
60
+
61
+ protected
62
+
63
+ def make_from_time(t, zone)
64
+
65
+ z =
66
+ zone ||
67
+ get_as_tzone(t) ||
68
+ get_tzone(t.zone) ||
69
+ get_local_tzone(t)
70
+
71
+ z ||= t.zone
72
+ # pass the abbreviation anyway,
73
+ # it will be used in the resulting error message
74
+
75
+ EoTime.new(t, z)
76
+ end
77
+
78
+ def make_from_date(d, zone)
79
+
80
+ make_from_time(
81
+ d.respond_to?(:to_time) ?
82
+ d.to_time :
83
+ Time.parse(d.strftime('%Y-%m-%d %H:%M:%S')),
84
+ zone)
85
+ end
86
+
87
+ def make_from_array(a, zone)
88
+
89
+ t = Time.utc(*a)
90
+ s = t.strftime("%Y-%m-%d %H:%M:%S.#{'%06d' % t.usec}")
91
+
92
+ make_from_string(s, zone)
93
+ end
94
+
95
+ def make_from_string(s, zone)
96
+
97
+ parse(s, zone: zone)
98
+ end
99
+
100
+ def make_from_numeric(f, zone)
101
+
102
+ EoTime.new(Time.now.to_f + f, zone)
103
+ end
104
+
105
+ def make_from_eotime(eot, zone)
106
+
107
+ return eot if zone == nil || zone == eot.zone
108
+ EoTime.new(eot.to_f, zone)
109
+ end
110
+ end
111
+ end
112
+
@@ -49,12 +49,12 @@ module EtOrbi
49
49
 
50
50
  def utc(*a)
51
51
 
52
- EtOrbi.make_from_array(a, EtOrbi.get_tzone('UTC'))
52
+ EtOrbi.send(:make_from_array, a, EtOrbi.get_tzone('UTC'))
53
53
  end
54
54
 
55
55
  def local(*a)
56
56
 
57
- EtOrbi.make_from_array(a, local_tzone)
57
+ EtOrbi.send(:make_from_array, a, local_tzone)
58
58
  end
59
59
  end
60
60
 
@@ -198,7 +198,7 @@ module EtOrbi
198
198
  end
199
199
 
200
200
  %w[
201
- year month day wday hour min sec usec asctime
201
+ year month day wday yday hour min sec usec asctime
202
202
  ].each do |m|
203
203
  define_method(m) { to_time.send(m) }
204
204
  end
@@ -223,7 +223,8 @@ module EtOrbi
223
223
  def +(t); inc(t, 1); end
224
224
  def -(t); inc(t, -1); end
225
225
 
226
- WEEK_S = 7 * 24 * 3600
226
+ DAY_S = 24 * 3600
227
+ WEEK_S = 7 * DAY_S
227
228
 
228
229
  def monthdays
229
230
 
@@ -308,12 +309,25 @@ module EtOrbi
308
309
  end
309
310
 
310
311
  alias translate localtime
312
+ alias in_time_zone localtime
311
313
 
312
314
  def wday_in_month
313
315
 
314
316
  [ count_weeks(-1), - count_weeks(1) ]
315
317
  end
316
318
 
319
+ def rweek
320
+
321
+ ((self - EtOrbi.make_time('2019-01-01 00:00:00', @zone)) / WEEK_S)
322
+ .floor + 1
323
+ end
324
+
325
+ def rday
326
+
327
+ ((self - EtOrbi.make_time('2019-01-01 00:00:00', @zone)) / DAY_S)
328
+ .floor + 1
329
+ end
330
+
317
331
  def reach(points)
318
332
 
319
333
  t = EoTime.new(self.to_f, @zone)
@@ -0,0 +1,132 @@
1
+
2
+ module EtOrbi
3
+
4
+ class << self
5
+
6
+ def get_tzone(o)
7
+
8
+ return o if o.is_a?(::TZInfo::Timezone)
9
+ return nil if o == nil
10
+ return determine_local_tzone if o == :local
11
+ return ::TZInfo::Timezone.get('Zulu') if o == 'Z'
12
+ return o.tzinfo if o.respond_to?(:tzinfo)
13
+
14
+ o = to_offset(o) if o.is_a?(Numeric)
15
+
16
+ return nil unless o.is_a?(String)
17
+
18
+ s = tweak_zone_name(o)
19
+
20
+ get_offset_tzone(s) ||
21
+ get_x_offset_tzone(s) ||
22
+ get_tzinfo_tzone(s)
23
+ end
24
+
25
+ protected
26
+
27
+ # custom timezones, no DST, just an offset, like "+08:00" or "-01:30"
28
+ #
29
+ def get_offset_tzone(str)
30
+
31
+ m = str.match(/\A([+-][0-1]?[0-9]):?([0-5][0-9])?\z/) rescue nil
32
+ #
33
+ # On Windows, the real encoding could be something other than UTF-8,
34
+ # and make the match fail
35
+ #
36
+ return nil unless m
37
+
38
+ tz = custom_tzs[str]
39
+ return tz if tz
40
+
41
+ hr = m[1].to_i
42
+ mn = m[2].to_i
43
+
44
+ hr = nil if hr.abs > 11
45
+ hr = nil if mn > 59
46
+ mn = -mn if hr && hr < 0
47
+
48
+ hr ?
49
+ custom_tzs[str] = create_offset_tzone(hr * 3600 + mn * 60, str) :
50
+ nil
51
+ end
52
+
53
+ if defined?(TZInfo::DataSources::ConstantOffsetDataTimezoneInfo)
54
+ # TZInfo >= 2.0.0
55
+
56
+ def create_offset_tzone(utc_off, id)
57
+
58
+ off = TZInfo::TimezoneOffset.new(utc_off, 0, id)
59
+ tzi = TZInfo::DataSources::ConstantOffsetDataTimezoneInfo.new(id, off)
60
+ tzi.create_timezone
61
+ end
62
+
63
+ else
64
+ # TZInfo < 2.0.0
65
+
66
+ def create_offset_tzone(utc_off, id)
67
+
68
+ tzi = TZInfo::TransitionDataTimezoneInfo.new(id)
69
+ tzi.offset(id, utc_off, 0, id)
70
+ tzi.create_timezone
71
+ end
72
+ end
73
+
74
+ def get_x_offset_tzone(str)
75
+
76
+ m = str.match(/\A_..-?[0-1]?\d:?(?:[0-5]\d)?(.+)\z/) rescue nil
77
+ #
78
+ # On Windows, the real encoding could be something other than UTF-8,
79
+ # and make the match fail (as in .get_offset_tzone above)
80
+
81
+ m ? ::TZInfo::Timezone.get(m[1]) : nil
82
+ end
83
+
84
+ def to_offset(n)
85
+
86
+ i = n.to_i
87
+ sn = i < 0 ? '-' : '+'; i = i.abs
88
+ hr = i / 3600; mn = i % 3600; sc = i % 60
89
+
90
+ sc > 0 ?
91
+ '%s%02d:%02d:%02d' % [ sn, hr, mn, sc ] :
92
+ '%s%02d:%02d' % [ sn, hr, mn ]
93
+ end
94
+
95
+ def get_tzinfo_tzone(name)
96
+
97
+ #return ::TZInfo::Timezone.get(name) rescue nil
98
+
99
+ loop do
100
+ return ::TZInfo::Timezone.get(name) if ZONES_OLSON.include?(name)
101
+ name = name[0..-2]
102
+ return nil if name.empty?
103
+ end
104
+ end
105
+
106
+ def windows_zone_code_x(zone_name)
107
+
108
+ a = [ '_' ]
109
+ a.concat(zone_name.split('/')[0, 2].collect { |s| s[0, 1].upcase })
110
+ a << '_' if a.size < 3
111
+
112
+ a.join
113
+ end
114
+
115
+ def get_local_tzone(t)
116
+
117
+ l = Time.local(t.year, t.month, t.day, t.hour, t.min, t.sec, t.usec)
118
+
119
+ (t.zone == l.zone) ? determine_local_tzone : nil
120
+ end
121
+
122
+ # https://api.rubyonrails.org/classes/ActiveSupport/TimeWithZone.html
123
+ #
124
+ # If it responds to #time_zone, then return that time zone.
125
+ #
126
+ def get_as_tzone(t)
127
+
128
+ t.respond_to?(:time_zone) ? t.time_zone : nil
129
+ end
130
+ end
131
+ end
132
+
@@ -0,0 +1,328 @@
1
+
2
+ module EtOrbi
3
+
4
+ class << self
5
+
6
+ ZONES_ISO8601_REX =
7
+ %r{
8
+ (?<=:\d\d)\s*
9
+ (?:
10
+ [-+]
11
+ (?:[0-1][0-9]|2[0-4])
12
+ (?:(?::)?(?:[0-5][0-9]|60))?
13
+ (?![-+])
14
+ |Z
15
+ )
16
+ }x
17
+
18
+ # https://en.wikipedia.org/wiki/ISO_8601
19
+ # Postel's law applies
20
+ #
21
+ def list_iso8601_zones(s)
22
+
23
+ s.scan(ZONES_ISO8601_REX).collect(&:strip)
24
+ end
25
+
26
+ ZONES_OLSON = (
27
+ ::TZInfo::Timezone.all
28
+ .collect { |z| z.name }.sort +
29
+ (0..12)
30
+ .collect { |i| [ "UTC-#{i}", "UTC+#{i}" ] })
31
+ .flatten
32
+ .sort_by(&:size)
33
+ .reverse
34
+
35
+ def extract_zone(str)
36
+
37
+ s = str.dup
38
+
39
+ zs = ZONES_OLSON
40
+ .inject([]) { |a, z|
41
+ i = s.index(z); next a unless i
42
+ a << z
43
+ s[i, z.length] = ''
44
+ a }
45
+
46
+ s.gsub!(ZONES_ISO8601_REX) { |m| zs << m.strip; '' } #if zs.empty?
47
+
48
+ zs = zs.sort_by { |z| str.index(z) }
49
+
50
+ [ s.strip, zs.last ]
51
+ end
52
+
53
+ def determine_local_tzone
54
+
55
+ # ENV has the priority
56
+
57
+ etz = ENV['TZ']
58
+
59
+ tz = etz && get_tzone(etz)
60
+ return tz if tz
61
+
62
+ # then Rails/ActiveSupport has the priority
63
+
64
+ if Time.respond_to?(:zone) && Time.zone.respond_to?(:tzinfo)
65
+ tz = Time.zone.tzinfo
66
+ return tz if tz
67
+ end
68
+
69
+ # then the operating system is queried
70
+
71
+ tz = ::TZInfo::Timezone.get(os_tz) rescue nil
72
+ return tz if tz
73
+
74
+ # then Ruby's time zone abbs are looked at CST, JST, CEST, ... :-(
75
+
76
+ tzs = determine_local_tzones
77
+ tz = (etz && tzs.find { |z| z.name == etz }) || tzs.first
78
+ return tz if tz
79
+
80
+ # then, fall back to GMT offest :-(
81
+
82
+ n = Time.now
83
+
84
+ get_tzone(n.zone) ||
85
+ get_tzone(n.strftime('%Z%z'))
86
+ end
87
+ alias zone determine_local_tzone
88
+
89
+ attr_accessor :_os_zone # test tool
90
+
91
+ def os_tz
92
+
93
+ return (@_os_zone == '' ? nil : @_os_zone) \
94
+ if defined?(@_os_zone) && @_os_zone
95
+
96
+ @os_tz ||= (debian_tz || centos_tz || osx_tz)
97
+ end
98
+
99
+ #
100
+ # system tz determination
101
+
102
+ def debian_tz
103
+
104
+ path = '/etc/timezone'
105
+
106
+ File.exist?(path) ? File.read(path).strip : nil
107
+ rescue; nil; end
108
+
109
+ def centos_tz
110
+
111
+ path = '/etc/sysconfig/clock'
112
+
113
+ File.open(path, 'rb') do |f|
114
+ until f.eof?
115
+ if m = f.readline.match(/ZONE="([^"]+)"/); return m[1]; end
116
+ end
117
+ end if File.exist?(path)
118
+
119
+ nil
120
+ rescue; nil; end
121
+
122
+ def osx_tz
123
+
124
+ path = '/etc/localtime'
125
+
126
+ File.symlink?(path) ?
127
+ File.readlink(path).split('/')[4..-1].join('/') :
128
+ nil
129
+ rescue; nil; end
130
+
131
+ def gather_tzs
132
+
133
+ { :debian => debian_tz, :centos => centos_tz, :osx => osx_tz }
134
+ end
135
+
136
+ # Semi-helpful, since it requires the current time
137
+ #
138
+ def windows_zone_name(zone_name, time)
139
+
140
+ twin = Time.utc(time.year, 1, 1) # winter
141
+ tsum = Time.utc(time.year, 7, 1) # summer
142
+
143
+ tz = ::TZInfo::Timezone.get(zone_name)
144
+ tzo = tz.period_for_local(time).utc_total_offset
145
+ tzop = tzo < 0 ? nil : '-'; tzo = tzo.abs
146
+ tzoh = tzo / 3600
147
+ tzos = tzo % 3600
148
+ tzos = tzos == 0 ? nil : ':%02d' % (tzos / 60)
149
+
150
+ abbs = [
151
+ tz.period_for_utc(twin).abbreviation.to_s,
152
+ tz.period_for_utc(tsum).abbreviation.to_s ]
153
+ .uniq
154
+
155
+ if abbs[0].match(/\A[A-Z]/)
156
+ [ abbs[0], tzop, tzoh, tzos, abbs[1] ]
157
+ .compact.join
158
+ else
159
+ [ windows_zone_code_x(zone_name), tzop, tzoh, tzos || ':00', zone_name ]
160
+ .collect(&:to_s).join
161
+ end
162
+ end
163
+
164
+ def tweak_zone_name(name)
165
+
166
+ return name unless (name.match(/./) rescue nil)
167
+ # to prevent invalid byte sequence in UTF-8..., gh-15
168
+
169
+ normalize(name) ||
170
+ unzz(name) ||
171
+ name
172
+ end
173
+
174
+ protected
175
+
176
+ def normalize(name)
177
+
178
+ ZONE_ALIASES[name.sub(/ Daylight /, ' Standard ')]
179
+ end
180
+
181
+ def unzz(name)
182
+
183
+ m = name.match(/\A([A-Z]{3,4})([+-])(\d{1,2}):?(\d{2})?\z/)
184
+ return nil unless m
185
+
186
+ abbs = [ m[1] ]; a = m[1]
187
+ abbs << "#{a}T" if a.size < 4
188
+
189
+ off =
190
+ (m[2] == '+' ? 1 : -1) *
191
+ (m[3].to_i * 3600 + (m[4] || '0').to_i * 60)
192
+
193
+ t = Time.now
194
+ twin = Time.utc(t.year, 1, 1) # winter
195
+ tsum = Time.utc(t.year, 7, 1) # summer
196
+
197
+ tz_all
198
+ .each { |tz|
199
+ abbs.each { |abb|
200
+ per = tz.period_for_utc(twin)
201
+ return tz.name \
202
+ if per.abbreviation.to_s == abb && per.utc_total_offset == off
203
+ per = tz.period_for_utc(tsum)
204
+ return tz.name \
205
+ if per.abbreviation.to_s == abb && per.utc_total_offset == off } }
206
+
207
+ nil
208
+ end
209
+
210
+ def determine_local_tzones
211
+
212
+ tabbs = (-6..5)
213
+ .collect { |i|
214
+ t = Time.now + i * 30 * 24 * 3600
215
+ "#{t.zone}_#{t.utc_offset}" }
216
+ .uniq
217
+ .sort
218
+ .join('|')
219
+
220
+ t = Time.now
221
+ #tu = t.dup.utc # /!\ dup is necessary, #utc modifies its target
222
+
223
+ twin = Time.local(t.year, 1, 1) # winter
224
+ tsum = Time.local(t.year, 7, 1) # summer
225
+
226
+ @tz_winter_summer ||= {}
227
+
228
+ @tz_winter_summer[tabbs] ||= tz_all
229
+ .select { |tz|
230
+ pw = tz.period_for_local(twin)
231
+ ps = tz.period_for_local(tsum)
232
+ tabbs ==
233
+ [ "#{pw.abbreviation}_#{pw.utc_total_offset}",
234
+ "#{ps.abbreviation}_#{ps.utc_total_offset}" ]
235
+ .uniq.sort.join('|') }
236
+
237
+ @tz_winter_summer[tabbs]
238
+ end
239
+
240
+ def custom_tzs; @custom_tzs ||= {}; end
241
+ def tz_all; @tz_all ||= ::TZInfo::Timezone.all; end
242
+ end
243
+
244
+ # https://docs.microsoft.com/en-us/windows-hardware/manufacture/desktop/default-time-zones
245
+ # https://support.microsoft.com/en-ca/help/973627/microsoft-time-zone-index-values
246
+ # https://ss64.com/nt/timezones.html
247
+
248
+ ZONE_ALIASES = {
249
+ 'Coordinated Universal Time' => 'UTC',
250
+ 'Afghanistan Standard Time' => 'Asia/Kabul',
251
+ 'FLE Standard Time' => 'Europe/Helsinki',
252
+ 'Central Europe Standard Time' => 'Europe/Prague',
253
+ 'UTC-11' => 'Etc/GMT+11',
254
+ 'W. Europe Standard Time' => 'Europe/Rome',
255
+ 'W. Central Africa Standard Time' => 'Africa/Lagos',
256
+ 'SA Western Standard Time' => 'America/La_Paz',
257
+ 'Pacific SA Standard Time' => 'America/Santiago',
258
+ 'Argentina Standard Time' => 'America/Argentina/Buenos_Aires',
259
+ 'Caucasus Standard Time' => 'Asia/Yerevan',
260
+ 'AUS Eastern Standard Time' => 'Australia/Sydney',
261
+ 'Azerbaijan Standard Time' => 'Asia/Baku',
262
+ 'Eastern Standard Time' => 'America/New_York',
263
+ 'Arab Standard Time' => 'Asia/Riyadh',
264
+ 'Bangladesh Standard Time' => 'Asia/Dhaka',
265
+ 'Belarus Standard Time' => 'Europe/Minsk',
266
+ 'Romance Standard Time' => 'Europe/Paris',
267
+ 'Central America Standard Time' => 'America/Belize',
268
+ 'Atlantic Standard Time' => 'Atlantic/Bermuda',
269
+ 'Venezuela Standard Time' => 'America/Caracas',
270
+ 'Central European Standard Time' => 'Europe/Warsaw',
271
+ 'South Africa Standard Time' => 'Africa/Johannesburg',
272
+ #'UTC' => 'Etc/UTC', # 'UTC' is good as is
273
+ 'E. South America Standard Time' => 'America/Sao_Paulo',
274
+ 'Central Asia Standard Time' => 'Asia/Almaty',
275
+ 'Singapore Standard Time' => 'Asia/Singapore',
276
+ 'Greenwich Standard Time' => 'Africa/Monrovia',
277
+ 'Cape Verde Standard Time' => 'Atlantic/Cape_Verde',
278
+ 'SE Asia Standard Time' => 'Asia/Bangkok',
279
+ 'SA Pacific Standard Time' => 'America/Bogota',
280
+ 'China Standard Time' => 'Asia/Shanghai',
281
+ 'Myanmar Standard Time' => 'Asia/Yangon',
282
+ 'E. Africa Standard Time' => 'Africa/Nairobi',
283
+ 'Hawaiian Standard Time' => 'Pacific/Honololu',
284
+ 'E. Europe Standard Time' => 'Europe/Nicosia',
285
+ 'Tokyo Standard Time' => 'Asia/Tokyo',
286
+ 'Egypt Standard Time' => 'Africa/Cairo',
287
+ 'SA Eastern Standard Time' => 'America/Cayenne',
288
+ 'GMT Standard Time' => 'Europe/London',
289
+ 'Fiji Standard Time' => 'Pacific/Fiji',
290
+ 'West Asia Standard Time' => 'Asia/Tashkent',
291
+ 'Georgian Standard Time' => 'Asia/Tbilisi',
292
+ 'GTB Standard Time' => 'Europe/Athens',
293
+ 'Greenland Standard Time' => 'America/Godthab',
294
+ 'West Pacific Standard Time' => 'Pacific/Guam',
295
+ 'Mauritius Standard Time' => 'Indian/Mauritius',
296
+ 'India Standard Time' => 'Asia/Kolkata',
297
+ 'Iran Standard Time' => 'Asia/Tehran',
298
+ 'Arabic Standard Time' => 'Asia/Baghdad',
299
+ 'Israel Standard Time' => 'Asia/Jerusalem',
300
+ 'Jordan Standard Time' => 'Asia/Amman',
301
+ 'UTC+12' => 'Etc/GMT-12',
302
+ 'Korea Standard Time' => 'Asia/Seoul',
303
+ 'Middle East Standard Time' => 'Asia/Beirut',
304
+ 'Central Standard Time (Mexico)' => 'America/Mexico_City',
305
+ 'Ulaanbaatar Standard Time' => 'Asia/Ulaanbaatar',
306
+ 'Morocco Standard Time' => 'Africa/Casablanca',
307
+ 'Namibia Standard Time' => 'Africa/Windhoek',
308
+ 'Nepal Standard Time' => 'Asia/Kathmandu',
309
+ 'Central Pacific Standard Time' => 'Etc/GMT-11',
310
+ 'New Zealand Standard Time' => 'Pacific/Auckland',
311
+ 'Arabian Standard Time' => 'Asia/Dubai',
312
+ 'Pakistan Standard Time' => 'Asia/Karachi',
313
+ 'Paraguay Standard Time' => 'America/Asuncion',
314
+ 'Pacific Standard Time' => 'America/Los_Angeles',
315
+ 'Russian Standard Time' => 'Europe/Moscow',
316
+ 'Samoa Standard Time' => 'Pacific/Pago_Pago',
317
+ 'UTC-02' => 'Etc/GMT+2',
318
+ 'Sri Lanka Standard Time' => 'Asia/Kolkata',
319
+ 'Syria Standard Time' => 'Asia/Damascus',
320
+ 'Taipei Standard Time' => 'Asia/Taipei',
321
+ 'Tonga Standard Time' => 'Pacific/Tongatapu',
322
+ 'Turkey Standard Time' => 'Asia/Istanbul',
323
+ 'Montevideo Standard Time' => 'America/Montevideo',
324
+
325
+ 'CST5CDT' => 'CST6CDT',
326
+ }
327
+ end
328
+