tilia-vobject 4.0.0.pre.alpha2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (193) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +19 -0
  3. data/.rubocop.yml +32 -0
  4. data/.simplecov +4 -0
  5. data/.travis.yml +3 -0
  6. data/CHANGELOG.sabre.md +626 -0
  7. data/CONTRIBUTING.md +25 -0
  8. data/Gemfile +17 -0
  9. data/Gemfile.lock +68 -0
  10. data/LICENSE +27 -0
  11. data/LICENSE.sabre +27 -0
  12. data/README.md +63 -0
  13. data/Rakefile +17 -0
  14. data/bin/vobject +7 -0
  15. data/lib/tilia/v_object/birthday_calendar_generator.rb +142 -0
  16. data/lib/tilia/v_object/cli.rb +582 -0
  17. data/lib/tilia/v_object/component/available.rb +107 -0
  18. data/lib/tilia/v_object/component/v_alarm.rb +114 -0
  19. data/lib/tilia/v_object/component/v_availability.rb +128 -0
  20. data/lib/tilia/v_object/component/v_calendar.rb +468 -0
  21. data/lib/tilia/v_object/component/v_card.rb +457 -0
  22. data/lib/tilia/v_object/component/v_event.rb +127 -0
  23. data/lib/tilia/v_object/component/v_free_busy.rb +81 -0
  24. data/lib/tilia/v_object/component/v_journal.rb +75 -0
  25. data/lib/tilia/v_object/component/v_time_zone.rb +51 -0
  26. data/lib/tilia/v_object/component/v_todo.rb +147 -0
  27. data/lib/tilia/v_object/component.rb +591 -0
  28. data/lib/tilia/v_object/date_time_parser.rb +486 -0
  29. data/lib/tilia/v_object/document.rb +218 -0
  30. data/lib/tilia/v_object/element_list.rb +18 -0
  31. data/lib/tilia/v_object/eof_exception.rb +8 -0
  32. data/lib/tilia/v_object/free_busy_data.rb +149 -0
  33. data/lib/tilia/v_object/free_busy_generator.rb +465 -0
  34. data/lib/tilia/v_object/i_tip/broker.rb +909 -0
  35. data/lib/tilia/v_object/i_tip/i_tip_exception.rb +9 -0
  36. data/lib/tilia/v_object/i_tip/message.rb +109 -0
  37. data/lib/tilia/v_object/i_tip/same_organizer_for_all_components_exception.rb +13 -0
  38. data/lib/tilia/v_object/i_tip.rb +10 -0
  39. data/lib/tilia/v_object/node.rb +192 -0
  40. data/lib/tilia/v_object/parameter.rb +327 -0
  41. data/lib/tilia/v_object/parse_exception.rb +7 -0
  42. data/lib/tilia/v_object/parser/json.rb +149 -0
  43. data/lib/tilia/v_object/parser/mime_dir.rb +543 -0
  44. data/lib/tilia/v_object/parser/parser.rb +61 -0
  45. data/lib/tilia/v_object/parser/xml/element/key_value.rb +60 -0
  46. data/lib/tilia/v_object/parser/xml/element.rb +11 -0
  47. data/lib/tilia/v_object/parser/xml.rb +322 -0
  48. data/lib/tilia/v_object/parser.rb +10 -0
  49. data/lib/tilia/v_object/property/binary.rb +96 -0
  50. data/lib/tilia/v_object/property/boolean.rb +57 -0
  51. data/lib/tilia/v_object/property/flat_text.rb +52 -0
  52. data/lib/tilia/v_object/property/float_value.rb +107 -0
  53. data/lib/tilia/v_object/property/i_calendar/cal_address.rb +49 -0
  54. data/lib/tilia/v_object/property/i_calendar/date.rb +15 -0
  55. data/lib/tilia/v_object/property/i_calendar/date_time.rb +330 -0
  56. data/lib/tilia/v_object/property/i_calendar/duration.rb +65 -0
  57. data/lib/tilia/v_object/property/i_calendar/period.rb +124 -0
  58. data/lib/tilia/v_object/property/i_calendar/recur.rb +173 -0
  59. data/lib/tilia/v_object/property/i_calendar.rb +14 -0
  60. data/lib/tilia/v_object/property/integer_value.rb +60 -0
  61. data/lib/tilia/v_object/property/text.rb +352 -0
  62. data/lib/tilia/v_object/property/time.rb +85 -0
  63. data/lib/tilia/v_object/property/unknown.rb +30 -0
  64. data/lib/tilia/v_object/property/uri.rb +78 -0
  65. data/lib/tilia/v_object/property/utc_offset.rb +56 -0
  66. data/lib/tilia/v_object/property/v_card/date.rb +31 -0
  67. data/lib/tilia/v_object/property/v_card/date_and_or_time.rb +343 -0
  68. data/lib/tilia/v_object/property/v_card/date_time.rb +22 -0
  69. data/lib/tilia/v_object/property/v_card/language_tag.rb +41 -0
  70. data/lib/tilia/v_object/property/v_card/time_stamp.rb +74 -0
  71. data/lib/tilia/v_object/property/v_card.rb +13 -0
  72. data/lib/tilia/v_object/property.rb +532 -0
  73. data/lib/tilia/v_object/reader.rb +73 -0
  74. data/lib/tilia/v_object/recur/event_iterator.rb +417 -0
  75. data/lib/tilia/v_object/recur/no_instances_exception.rb +11 -0
  76. data/lib/tilia/v_object/recur/r_date_iterator.rb +138 -0
  77. data/lib/tilia/v_object/recur/r_rule_iterator.rb +717 -0
  78. data/lib/tilia/v_object/recur.rb +10 -0
  79. data/lib/tilia/v_object/settings.rb +32 -0
  80. data/lib/tilia/v_object/splitter/i_calendar.rb +95 -0
  81. data/lib/tilia/v_object/splitter/splitter_interface.rb +31 -0
  82. data/lib/tilia/v_object/splitter/v_card.rb +56 -0
  83. data/lib/tilia/v_object/splitter.rb +9 -0
  84. data/lib/tilia/v_object/string_util.rb +58 -0
  85. data/lib/tilia/v_object/time_zone_data/exchange_zones.rb +96 -0
  86. data/lib/tilia/v_object/time_zone_data/lotus_zones.rb +104 -0
  87. data/lib/tilia/v_object/time_zone_data/php_zones.rb +49 -0
  88. data/lib/tilia/v_object/time_zone_data/windows_zones.rb +121 -0
  89. data/lib/tilia/v_object/time_zone_data.rb +10 -0
  90. data/lib/tilia/v_object/time_zone_util.rb +213 -0
  91. data/lib/tilia/v_object/uuid_util.rb +51 -0
  92. data/lib/tilia/v_object/v_card_converter.rb +354 -0
  93. data/lib/tilia/v_object/version.rb +9 -0
  94. data/lib/tilia/v_object/writer.rb +56 -0
  95. data/lib/tilia/v_object.rb +45 -0
  96. data/lib/tilia/vobject.rb +1 -0
  97. data/resources/schema/xcal.rng +1192 -0
  98. data/resources/schema/xcard.rng +388 -0
  99. data/test/test_helper.rb +56 -0
  100. data/test/v_object/attach_issue_test.rb +19 -0
  101. data/test/v_object/birthday_calendar_generator_test.rb +463 -0
  102. data/test/v_object/cli_mock.rb +19 -0
  103. data/test/v_object/cli_test.rb +460 -0
  104. data/test/v_object/component/available_test.rb +59 -0
  105. data/test/v_object/component/v_alarm_test.rb +160 -0
  106. data/test/v_object/component/v_availability_test.rb +388 -0
  107. data/test/v_object/component/v_calendar_test.rb +646 -0
  108. data/test/v_object/component/v_card_test.rb +258 -0
  109. data/test/v_object/component/v_event_test.rb +85 -0
  110. data/test/v_object/component/v_free_busy_test.rb +59 -0
  111. data/test/v_object/component/v_journal_test.rb +85 -0
  112. data/test/v_object/component/v_time_zone_test.rb +47 -0
  113. data/test/v_object/component/v_todo_test.rb +172 -0
  114. data/test/v_object/component_test.rb +419 -0
  115. data/test/v_object/date_time_parser_test.rb +526 -0
  116. data/test/v_object/document_test.rb +71 -0
  117. data/test/v_object/element_list_test.rb +27 -0
  118. data/test/v_object/em_client_test.rb +53 -0
  119. data/test/v_object/empty_parameter_test.rb +65 -0
  120. data/test/v_object/empty_value_issue_test.rb +25 -0
  121. data/test/v_object/fake_component.rb +21 -0
  122. data/test/v_object/free_busy_data_test.rb +285 -0
  123. data/test/v_object/free_busy_generator_test.rb +637 -0
  124. data/test/v_object/google_colon_escaping_test.rb +27 -0
  125. data/test/v_object/i_calendar/attach_parse_test.rb +24 -0
  126. data/test/v_object/i_tip/broker_attendee_reply_test.rb +1042 -0
  127. data/test/v_object/i_tip/broker_delete_event_test.rb +175 -0
  128. data/test/v_object/i_tip/broker_new_event_test.rb +440 -0
  129. data/test/v_object/i_tip/broker_process_message_test.rb +153 -0
  130. data/test/v_object/i_tip/broker_process_reply_test.rb +402 -0
  131. data/test/v_object/i_tip/broker_tester.rb +71 -0
  132. data/test/v_object/i_tip/broker_update_event_test.rb +763 -0
  133. data/test/v_object/i_tip/evolution_test.rb +2644 -0
  134. data/test/v_object/i_tip/message_test.rb +25 -0
  135. data/test/v_object/issue153.vcf +352 -0
  136. data/test/v_object/issue153_test.rb +12 -0
  137. data/test/v_object/issue26_test.rb +25 -0
  138. data/test/v_object/issue36_work_around_test.rb +37 -0
  139. data/test/v_object/issue40_test.rb +26 -0
  140. data/test/v_object/issue64.vcf +351 -0
  141. data/test/v_object/issue64_test.rb +17 -0
  142. data/test/v_object/issue96_test.rb +22 -0
  143. data/test/v_object/issue_undefined_index_test.rb +24 -0
  144. data/test/v_object/j_cal_test.rb +150 -0
  145. data/test/v_object/j_card_test.rb +192 -0
  146. data/test/v_object/line_folding_issue_test.rb +19 -0
  147. data/test/v_object/mock_document.rb +6 -0
  148. data/test/v_object/parameter_test.rb +109 -0
  149. data/test/v_object/parser/json_test.rb +370 -0
  150. data/test/v_object/parser/mime_dir_test.rb +14 -0
  151. data/test/v_object/parser/quoted_printable_test.rb +78 -0
  152. data/test/v_object/parser/xml_test.rb +2563 -0
  153. data/test/v_object/property/binary_test.rb +12 -0
  154. data/test/v_object/property/boolean_test.rb +18 -0
  155. data/test/v_object/property/compound_test.rb +43 -0
  156. data/test/v_object/property/float_test.rb +20 -0
  157. data/test/v_object/property/i_calendar/cal_address_test.rb +26 -0
  158. data/test/v_object/property/i_calendar/date_time_test.rb +303 -0
  159. data/test/v_object/property/i_calendar/duration_test.rb +14 -0
  160. data/test/v_object/property/i_calendar/recur_test.rb +39 -0
  161. data/test/v_object/property/text_test.rb +81 -0
  162. data/test/v_object/property/v_card/date_and_or_time_test.rb +205 -0
  163. data/test/v_object/property/v_card/language_tag_test.rb +35 -0
  164. data/test/v_object/property_test.rb +338 -0
  165. data/test/v_object/reader_test.rb +403 -0
  166. data/test/v_object/recur/event_iterator/by_month_in_daily_test.rb +52 -0
  167. data/test/v_object/recur/event_iterator/by_set_pos_hang_test.rb +55 -0
  168. data/test/v_object/recur/event_iterator/expand_floating_times_test.rb +109 -0
  169. data/test/v_object/recur/event_iterator/fifth_tuesday_problem_test.rb +45 -0
  170. data/test/v_object/recur/event_iterator/incorrect_expand_test.rb +53 -0
  171. data/test/v_object/recur/event_iterator/infinite_loop_problem_test.rb +75 -0
  172. data/test/v_object/recur/event_iterator/issue48_test.rb +43 -0
  173. data/test/v_object/recur/event_iterator/issue50_test.rb +123 -0
  174. data/test/v_object/recur/event_iterator/main_test.rb +1222 -0
  175. data/test/v_object/recur/event_iterator/missing_overridden_test.rb +55 -0
  176. data/test/v_object/recur/event_iterator/no_instances_test.rb +32 -0
  177. data/test/v_object/recur/event_iterator/override_first_event_test.rb +106 -0
  178. data/test/v_object/recur/r_date_iterator_test.rb +44 -0
  179. data/test/v_object/recur/r_rule_iterator_test.rb +608 -0
  180. data/test/v_object/recurrence_iterator/UntilRespectsTimezoneTest.ics +39 -0
  181. data/test/v_object/slash_r_test.rb +15 -0
  182. data/test/v_object/splitter/i_calendar_test.rb +299 -0
  183. data/test/v_object/splitter/v_card_test.rb +173 -0
  184. data/test/v_object/string_util_test.rb +37 -0
  185. data/test/v_object/test_case.rb +42 -0
  186. data/test/v_object/time_zone_util_test.rb +271 -0
  187. data/test/v_object/uuid_util_test.rb +18 -0
  188. data/test/v_object/v_card21_test.rb +43 -0
  189. data/test/v_object/v_card_converter_test.rb +419 -0
  190. data/test/v_object/version_test.rb +15 -0
  191. data/test/v_object/writer_test.rb +33 -0
  192. data/tilia-vobject.gemspec +17 -0
  193. metadata +308 -0
@@ -0,0 +1,10 @@
1
+ module Tilia
2
+ module VObject
3
+ module Recur
4
+ require 'tilia/v_object/recur/no_instances_exception'
5
+ require 'tilia/v_object/recur/event_iterator'
6
+ require 'tilia/v_object/recur/r_date_iterator'
7
+ require 'tilia/v_object/recur/r_rule_iterator'
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,32 @@
1
+ module Tilia
2
+ module VObject
3
+ # This class provides a list of global defaults for vobject.
4
+ #
5
+ # Some of these started to appear in various classes, so it made a bit more
6
+ # sense to centralize them, so it's easier for user to find and change these.
7
+ #
8
+ # The global nature of them does mean that changing the settings for one
9
+ # instance has a global influence.
10
+ class Settings
11
+ # The minimum date we accept for various calculations with dates, such as
12
+ # recurrences.
13
+ #
14
+ # The choice of 1900 is pretty arbitrary, but it covers most common
15
+ # use-cases. In particular, it covers birthdates for virtually everyone
16
+ # alive on earth, which is less than 5 people at the time of writing.
17
+ @min_date = '1900-01-01'
18
+
19
+ # The maximum date we accept for various calculations with dates, such as
20
+ # recurrences.
21
+ #
22
+ # The choice of 2100 is pretty arbitrary, but should cover most
23
+ # appointments made for many years to come.
24
+ @max_date = '2100-01-01'
25
+
26
+ class << self
27
+ attr_accessor :min_date
28
+ attr_accessor :max_date
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,95 @@
1
+ require 'digest'
2
+ module Tilia
3
+ module VObject
4
+ module Splitter
5
+ # Splitter.
6
+ #
7
+ # This class is responsible for splitting up iCalendar objects.
8
+ #
9
+ # This class expects a single VCALENDAR object with one or more
10
+ # calendar-objects inside. Objects with identical UID's will be combined into
11
+ # a single object.
12
+ class ICalendar
13
+ include SplitterInterface
14
+
15
+ # Timezones.
16
+ #
17
+ # @var array
18
+ # RUBY: attr_accessor :vtimezones
19
+
20
+ # iCalendar objects.
21
+ #
22
+ # @var array
23
+ # RUBY: attr_accessor :objects
24
+
25
+ # Constructor.
26
+ #
27
+ # The splitter should receive an readable file stream as it's input.
28
+ #
29
+ # @param resource input
30
+ # @param int options Parser options, see the OPTIONS constants.
31
+ def initialize(input, options = 0)
32
+ @vtimezones = {}
33
+ @objects = {}
34
+
35
+ data = Reader.read(input, options)
36
+
37
+ unless data.is_a?(Component::VCalendar)
38
+ fail ParseException, 'Supplied input could not be parsed as VCALENDAR.'
39
+ end
40
+
41
+ data.children.each do |component|
42
+ next unless component.is_a? Component
43
+
44
+ if component.name == 'VTIMEZONE'
45
+ @vtimezones[component['TZID'].to_s] = component
46
+ next
47
+ end
48
+
49
+ # Get component UID for recurring Events search
50
+ if component['UID'].blank?
51
+ component['UID'] = "#{Digest::SHA1.hexdigest(Time.now.to_s + rand.to_s)}-vobjectimport"
52
+ end
53
+
54
+ uid = component['UID'].to_s
55
+
56
+ # Take care of recurring events
57
+ @objects[uid] = Component::VCalendar.new unless @objects.key?(uid)
58
+
59
+ @objects[uid].add(component.dup)
60
+ end
61
+ end
62
+
63
+ # Every time self.next is called, a new object will be parsed, until we
64
+ # hit the end of the stream.
65
+ #
66
+ # When the end is reached, null will be returned.
67
+ #
68
+ # @return Sabre\VObject\Component|null
69
+ def next
70
+ key = @objects.keys.first
71
+
72
+ if key
73
+ object = @objects.delete(key)
74
+
75
+ # create our baseobject
76
+ object['VERSION'] = '2.0'
77
+ object['PRODID'] = "-//Tilia//Tilia VObject #{Version::VERSION}//EN"
78
+ object['CALSCALE'] = 'GREGORIAN'
79
+
80
+ # add vtimezone information to obj (if we have it)
81
+ @vtimezones.keys.each do |vtimezone|
82
+ object.add(@vtimezones[vtimezone])
83
+ end
84
+
85
+ return object
86
+ else
87
+ return nil
88
+ end
89
+
90
+ nil
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,31 @@
1
+ module Tilia
2
+ module VObject
3
+ module Splitter
4
+ # VObject splitter.
5
+ #
6
+ # The splitter is responsible for reading a large vCard or iCalendar object,
7
+ # and splitting it into multiple objects.
8
+ #
9
+ # This is for example for Card and CalDAV, which require every event and vcard
10
+ # to exist in their own objects, instead of one large one.
11
+ module SplitterInterface
12
+ # Constructor.
13
+ #
14
+ # The splitter should receive an readable file stream as it's input.
15
+ #
16
+ # @param resource input
17
+ def initialize(_input)
18
+ end
19
+
20
+ # Every time self.next is called, a new object will be parsed, until we
21
+ # hit the end of the stream.
22
+ #
23
+ # When the end is reached, null will be returned.
24
+ #
25
+ # @return Sabre\VObject\Component|null
26
+ def next
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,56 @@
1
+ module Tilia
2
+ module VObject
3
+ module Splitter
4
+ # Splitter.
5
+ #
6
+ # This class is responsible for splitting up VCard objects.
7
+ #
8
+ # It is assumed that the input stream contains 1 or more VCARD objects. This
9
+ # class checks for BEGIN:VCARD and END:VCARD and parses each encountered
10
+ # component individually.
11
+ class VCard
12
+ include SplitterInterface
13
+ # File handle.
14
+ #
15
+ # @var resource
16
+ # RUBY: attr_accessor :input
17
+
18
+ # Persistent parser.
19
+ #
20
+ # @var MimeDir
21
+ # RUBY: attr_accessor :parser
22
+
23
+ # Constructor.
24
+ #
25
+ # The splitter should receive an readable file stream as it's input.
26
+ #
27
+ # @param resource input
28
+ # @param int options Parser options, see the OPTIONS constants.
29
+ def initialize(input, options = 0)
30
+ @input = input
31
+ @parser = Parser::MimeDir.new(input, options)
32
+ end
33
+
34
+ # Every time self.next is called, a new object will be parsed, until we
35
+ # hit the end of the stream.
36
+ #
37
+ # When the end is reached, null will be returned.
38
+ #
39
+ # @return Sabre\VObject\Component|null
40
+ def next
41
+ begin
42
+ object = @parser.parse
43
+
44
+ unless object.is_a?(Component::VCard)
45
+ fail ParseException, 'The supplied input contained non-VCARD data.'
46
+ end
47
+ rescue EofException
48
+ return nil
49
+ end
50
+
51
+ object
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,9 @@
1
+ module Tilia
2
+ module VObject
3
+ module Splitter
4
+ require 'tilia/v_object/splitter/splitter_interface'
5
+ require 'tilia/v_object/splitter/i_calendar'
6
+ require 'tilia/v_object/splitter/v_card'
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,58 @@
1
+ module Tilia
2
+ module VObject
3
+ # Useful utilities for working with various strings.
4
+ class StringUtil
5
+ # Returns true or false depending on if a string is valid UTF-8.
6
+ #
7
+ # @param string str
8
+ #
9
+ # @return bool
10
+ def self.utf8?(str)
11
+ fail ArgumentError, 'str needs to be a String' unless str.is_a?(String)
12
+ # Control characters
13
+ return false if str =~ /[\x00-\x08\x0B-\x0C\x0E\x0F]/
14
+
15
+ str.encoding.to_s == 'UTF-8' && str.valid_encoding?
16
+ end
17
+
18
+ # This method tries its best to convert the input string to UTF-8.
19
+ #
20
+ # Currently only ISO-5991-1 input and UTF-8 input is supported, but this
21
+ # may be expanded upon if we receive other examples.
22
+ #
23
+ # @param string str
24
+ #
25
+ # @return string
26
+ def self.convert_to_utf8(str)
27
+ cd = CharDet.detect(str)
28
+
29
+ # Best solution I could find ...
30
+ if cd['confidence'] > 0.4 && cd['encoding'] =~ /(?:windows|iso)/i
31
+ str = str.encode('UTF-8', cd['encoding'])
32
+ end
33
+
34
+ # Removing any control characters
35
+ str.gsub(/(?:[\x00-\x08\x0B-\x0C\x0E-\x1F\x7F])/, '')
36
+ end
37
+
38
+ # TODO: document
39
+ def self.mb_strcut(string, length)
40
+ return '' if string == ''
41
+
42
+ string = string.clone
43
+ tmp = ''
44
+ while tmp.bytesize <= length
45
+ tmp += string[0]
46
+ string[0] = ''
47
+ end
48
+
49
+ # Last char was utf-8 multibyte
50
+ if tmp.bytesize > length
51
+ string[0] = tmp[-1] + string[0].to_s
52
+ tmp[-1] = ''
53
+ end
54
+ tmp
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,96 @@
1
+ module Tilia
2
+ module VObject
3
+ module TimeZoneData
4
+ # Microsoft exchange timezones
5
+ # Source:
6
+ # http://msdn.microsoft.com/en-us/library/ms988620%28v=exchg.65%29.aspx.
7
+ #
8
+ # Correct timezones deduced with help from:
9
+ # http://en.wikipedia.org/wiki/List_of_tz_database_time_zones
10
+ module ExchangeZones
11
+ def self.list
12
+ {
13
+ 'Universal Coordinated Time' => 'UTC',
14
+ 'Casablanca, Monrovia' => 'Africa/Casablanca',
15
+ 'Greenwich Mean Time: Dublin, Edinburgh, Lisbon, London' => 'Europe/Lisbon',
16
+ 'Greenwich Mean Time; Dublin, Edinburgh, London' => 'Europe/London',
17
+ 'Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna' => 'Europe/Berlin',
18
+ 'Belgrade, Pozsony, Budapest, Ljubljana, Prague' => 'Europe/Prague',
19
+ 'Brussels, Copenhagen, Madrid, Paris' => 'Europe/Paris',
20
+ 'Paris, Madrid, Brussels, Copenhagen' => 'Europe/Paris',
21
+ 'Prague, Central Europe' => 'Europe/Prague',
22
+ 'Sarajevo, Skopje, Sofija, Vilnius, Warsaw, Zagreb' => 'Europe/Sarajevo',
23
+ 'West Central Africa' => 'Africa/Luanda', # This was a best guess
24
+ 'Athens, Istanbul, Minsk' => 'Europe/Athens',
25
+ 'Bucharest' => 'Europe/Bucharest',
26
+ 'Cairo' => 'Africa/Cairo',
27
+ 'Harare, Pretoria' => 'Africa/Harare',
28
+ 'Helsinki, Riga, Tallinn' => 'Europe/Helsinki',
29
+ 'Israel, Jerusalem Standard Time' => 'Asia/Jerusalem',
30
+ 'Baghdad' => 'Asia/Baghdad',
31
+ 'Arab, Kuwait, Riyadh' => 'Asia/Kuwait',
32
+ 'Moscow, St. Petersburg, Volgograd' => 'Europe/Moscow',
33
+ 'East Africa, Nairobi' => 'Africa/Nairobi',
34
+ 'Tehran' => 'Asia/Tehran',
35
+ 'Abu Dhabi, Muscat' => 'Asia/Muscat', # Best guess
36
+ 'Baku, Tbilisi, Yerevan' => 'Asia/Baku',
37
+ 'Kabul' => 'Asia/Kabul',
38
+ 'Ekaterinburg' => 'Asia/Yekaterinburg',
39
+ 'Islamabad, Karachi, Tashkent' => 'Asia/Karachi',
40
+ 'Kolkata, Chennai, Mumbai, New Delhi, India Standard Time' => 'Asia/Calcutta',
41
+ 'Kathmandu, Nepal' => 'Asia/Kathmandu',
42
+ 'Almaty, Novosibirsk, North Central Asia' => 'Asia/Almaty',
43
+ 'Astana, Dhaka' => 'Asia/Dhaka',
44
+ 'Sri Jayawardenepura, Sri Lanka' => 'Asia/Colombo',
45
+ 'Rangoon' => 'Asia/Rangoon',
46
+ 'Bangkok, Hanoi, Jakarta' => 'Asia/Bangkok',
47
+ 'Krasnoyarsk' => 'Asia/Krasnoyarsk',
48
+ 'Beijing, Chongqing, Hong Kong SAR, Urumqi' => 'Asia/Shanghai',
49
+ 'Irkutsk, Ulaan Bataar' => 'Asia/Irkutsk',
50
+ 'Kuala Lumpur, Singapore' => 'Asia/Singapore',
51
+ 'Perth, Western Australia' => 'Australia/Perth',
52
+ 'Taipei' => 'Asia/Taipei',
53
+ 'Osaka, Sapporo, Tokyo' => 'Asia/Tokyo',
54
+ 'Seoul, Korea Standard time' => 'Asia/Seoul',
55
+ 'Yakutsk' => 'Asia/Yakutsk',
56
+ 'Adelaide, Central Australia' => 'Australia/Adelaide',
57
+ 'Darwin' => 'Australia/Darwin',
58
+ 'Brisbane, East Australia' => 'Australia/Brisbane',
59
+ 'Canberra, Melbourne, Sydney, Hobart (year 2000 only)' => 'Australia/Sydney',
60
+ 'Guam, Port Moresby' => 'Pacific/Guam',
61
+ 'Hobart, Tasmania' => 'Australia/Hobart',
62
+ 'Vladivostok' => 'Asia/Vladivostok',
63
+ 'Magadan, Solomon Is., New Caledonia' => 'Asia/Magadan',
64
+ 'Auckland, Wellington' => 'Pacific/Auckland',
65
+ 'Fiji Islands, Kamchatka, Marshall Is.' => 'Pacific/Fiji',
66
+ 'Nuku\'alofa, Tonga' => 'Pacific/Tongatapu',
67
+ 'Azores' => 'Atlantic/Azores',
68
+ 'Cape Verde Is.' => 'Atlantic/Cape_Verde',
69
+ 'Mid-Atlantic' => 'America/Noronha',
70
+ 'Brasilia' => 'America/Sao_Paulo', # Best guess
71
+ 'Buenos Aires' => 'America/Argentina/Buenos_Aires',
72
+ 'Greenland' => 'America/Godthab',
73
+ 'Newfoundland' => 'America/St_Johns',
74
+ 'Atlantic Time (Canada)' => 'America/Halifax',
75
+ 'Caracas, La Paz' => 'America/Caracas',
76
+ 'Santiago' => 'America/Santiago',
77
+ 'Bogota, Lima, Quito' => 'America/Bogota',
78
+ 'Eastern Time (US & Canada)' => 'America/New_York',
79
+ 'Indiana (East)' => 'America/Indiana/Indianapolis',
80
+ 'Central America' => 'America/Guatemala',
81
+ 'Central Time (US & Canada)' => 'America/Chicago',
82
+ 'Mexico City, Tegucigalpa' => 'America/Mexico_City',
83
+ 'Saskatchewan' => 'America/Edmonton',
84
+ 'Arizona' => 'America/Phoenix',
85
+ 'Mountain Time (US & Canada)' => 'America/Denver', # Best guess
86
+ 'Pacific Time (US & Canada); Tijuana' => 'America/Los_Angeles', # Best guess
87
+ 'Alaska' => 'America/Anchorage',
88
+ 'Hawaii' => 'Pacific/Honolulu',
89
+ 'Midway Island, Samoa' => 'Pacific/Midway',
90
+ 'Eniwetok, Kwajalein, Dateline Time' => 'Pacific/Kwajalein'
91
+ }
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,104 @@
1
+ module Tilia
2
+ module VObject
3
+ module TimeZoneData
4
+ # The following list are timezone names that could be generated by
5
+ # Lotus / Domino.
6
+ module LotusZones
7
+ def self.list
8
+ {
9
+ 'Dateline' => 'Etc/GMT-12',
10
+ 'Samoa' => 'Pacific/Apia',
11
+ 'Hawaiian' => 'Pacific/Honolulu',
12
+ 'Alaskan' => 'America/Anchorage',
13
+ 'Pacific' => 'America/Los_Angeles',
14
+ 'Pacific Standard Time' => 'America/Los_Angeles',
15
+ 'Mexico Standard Time 2' => 'America/Chihuahua',
16
+ 'Mountain' => 'America/Denver',
17
+ # 'Mountain Standard Time' => 'America/Chihuahua', # conflict with windows timezones.
18
+ 'US Mountain' => 'America/Phoenix',
19
+ 'Canada Central' => 'America/Edmonton',
20
+ 'Central America' => 'America/Guatemala',
21
+ 'Central' => 'America/Chicago',
22
+ # 'Central Standard Time' => 'America/Mexico_City', # conflict with windows timezones.
23
+ 'Mexico' => 'America/Mexico_City',
24
+ 'Eastern' => 'America/New_York',
25
+ 'SA Pacific' => 'America/Bogota',
26
+ 'US Eastern' => 'America/Indiana/Indianapolis',
27
+ 'Venezuela' => 'America/Caracas',
28
+ 'Atlantic' => 'America/Halifax',
29
+ 'Central Brazilian' => 'America/Manaus',
30
+ 'Pacific SA' => 'America/Santiago',
31
+ 'SA Western' => 'America/La_Paz',
32
+ 'Newfoundland' => 'America/St_Johns',
33
+ 'Argentina' => 'America/Argentina/Buenos_Aires',
34
+ 'E. South America' => 'America/Belem',
35
+ 'Greenland' => 'America/Godthab',
36
+ 'Montevideo' => 'America/Montevideo',
37
+ 'SA Eastern' => 'America/Belem',
38
+ # 'Mid-Atlantic' => 'Etc/GMT-2', # conflict with windows timezones.
39
+ 'Azores' => 'Atlantic/Azores',
40
+ 'Cape Verde' => 'Atlantic/Cape_Verde',
41
+ 'Greenwich' => 'Atlantic/Reykjavik', # No I'm serious.. Greenwich is not GMT.
42
+ 'Morocco' => 'Africa/Casablanca',
43
+ 'Central Europe' => 'Europe/Prague',
44
+ 'Central European' => 'Europe/Sarajevo',
45
+ 'Romance' => 'Europe/Paris',
46
+ 'W. Central Africa' => 'Africa/Lagos', # Best guess
47
+ 'W. Europe' => 'Europe/Amsterdam',
48
+ 'E. Europe' => 'Europe/Minsk',
49
+ 'Egypt' => 'Africa/Cairo',
50
+ 'FLE' => 'Europe/Helsinki',
51
+ 'GTB' => 'Europe/Athens',
52
+ 'Israel' => 'Asia/Jerusalem',
53
+ 'Jordan' => 'Asia/Amman',
54
+ 'Middle East' => 'Asia/Beirut',
55
+ 'Namibia' => 'Africa/Windhoek',
56
+ 'South Africa' => 'Africa/Harare',
57
+ 'Arab' => 'Asia/Kuwait',
58
+ 'Arabic' => 'Asia/Baghdad',
59
+ 'E. Africa' => 'Africa/Nairobi',
60
+ 'Georgian' => 'Asia/Tbilisi',
61
+ 'Russian' => 'Europe/Moscow',
62
+ 'Iran' => 'Asia/Tehran',
63
+ 'Arabian' => 'Asia/Muscat',
64
+ 'Armenian' => 'Asia/Yerevan',
65
+ 'Azerbijan' => 'Asia/Baku',
66
+ 'Caucasus' => 'Asia/Yerevan',
67
+ 'Mauritius' => 'Indian/Mauritius',
68
+ 'Afghanistan' => 'Asia/Kabul',
69
+ 'Ekaterinburg' => 'Asia/Yekaterinburg',
70
+ 'Pakistan' => 'Asia/Karachi',
71
+ 'West Asia' => 'Asia/Tashkent',
72
+ 'India' => 'Asia/Calcutta',
73
+ 'Sri Lanka' => 'Asia/Colombo',
74
+ 'Nepal' => 'Asia/Kathmandu',
75
+ 'Central Asia' => 'Asia/Dhaka',
76
+ 'N. Central Asia' => 'Asia/Almaty',
77
+ 'Myanmar' => 'Asia/Rangoon',
78
+ 'North Asia' => 'Asia/Krasnoyarsk',
79
+ 'SE Asia' => 'Asia/Bangkok',
80
+ 'China' => 'Asia/Shanghai',
81
+ 'North Asia East' => 'Asia/Irkutsk',
82
+ 'Singapore' => 'Asia/Singapore',
83
+ 'Taipei' => 'Asia/Taipei',
84
+ 'W. Australia' => 'Australia/Perth',
85
+ 'Korea' => 'Asia/Seoul',
86
+ 'Tokyo' => 'Asia/Tokyo',
87
+ 'Yakutsk' => 'Asia/Yakutsk',
88
+ 'AUS Central' => 'Australia/Darwin',
89
+ 'Cen. Australia' => 'Australia/Adelaide',
90
+ 'AUS Eastern' => 'Australia/Sydney',
91
+ 'E. Australia' => 'Australia/Brisbane',
92
+ 'Tasmania' => 'Australia/Hobart',
93
+ 'Vladivostok' => 'Asia/Vladivostok',
94
+ 'West Pacific' => 'Pacific/Guam',
95
+ 'Central Pacific' => 'Asia/Magadan',
96
+ 'Fiji' => 'Pacific/Fiji',
97
+ 'New Zealand' => 'Pacific/Auckland',
98
+ 'Tonga' => 'Pacific/Tongatapu'
99
+ }
100
+ end
101
+ end
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,49 @@
1
+ module Tilia
2
+ module VObject
3
+ module TimeZoneData
4
+ # A list of PHP timezones that were supported until 5.5.9, removed in
5
+ # PHP 5.5.10 and re-introduced in PHP 5.5.17.
6
+ #
7
+ # DateTimeZone::list_identifiers(DateTimeZone::ALL_WITH_BC) returns them,
8
+ # but they are invalid for new Date_time_zone. Fixed in PHP 5.5.17.
9
+ # https://bugs.php.net/bug.php?id=66985
10
+ #
11
+ # Some more info here:
12
+ # http://evertpot.com/php-5-5-10-timezone-changes/
13
+ module PhpZones
14
+ def self.list
15
+ {
16
+ 'CST6CDT' => 'America/Chicago',
17
+ 'Cuba' => 'America/Havana',
18
+ 'Egypt' => 'Africa/Cairo',
19
+ 'Eire' => 'Europe/Dublin',
20
+ 'EST5EDT' => 'America/New_York',
21
+ 'Factory' => 'UTC',
22
+ 'GB-Eire' => 'Europe/London',
23
+ 'GMT0' => 'UTC',
24
+ 'Greenwich' => 'UTC',
25
+ 'Hongkong' => 'Asia/Hong_Kong',
26
+ 'Iceland' => 'Atlantic/Reykjavik',
27
+ 'Iran' => 'Asia/Tehran',
28
+ 'Israel' => 'Asia/Jerusalem',
29
+ 'Jamaica' => 'America/Jamaica',
30
+ 'Japan' => 'Asia/Tokyo',
31
+ 'Kwajalein' => 'Pacific/Kwajalein',
32
+ 'Libya' => 'Africa/Tripoli',
33
+ 'MST7MDT' => 'America/Denver',
34
+ 'Navajo' => 'America/Denver',
35
+ 'NZ-CHAT' => 'Pacific/Chatham',
36
+ 'Poland' => 'Europe/Warsaw',
37
+ 'Portugal' => 'Europe/Lisbon',
38
+ 'PST8PDT' => 'America/Los_Angeles',
39
+ 'Singapore' => 'Asia/Singapore',
40
+ 'Turkey' => 'Europe/Istanbul',
41
+ 'Universal' => 'UTC',
42
+ 'W-SU' => 'Europe/Moscow',
43
+ 'Zulu' => 'UTC'
44
+ }
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end