football-timezones 0.0.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f628a9691af73e5ab5f28f1be1cd09bae28ecf6e064e7efc4cb91867c182bf0a
4
- data.tar.gz: 6273d92f3482d84bf785b6c161e4b71cf84172802c3ad40ffe3119f45c7f5fdf
3
+ metadata.gz: d8574fc2a4c6312eb5f3080f41b1f08a353618b65f049876b2d1c90752e1f579
4
+ data.tar.gz: 001a40fbd239ab29c44104f1c67e1f033a4389974ce5699ffd9f61ce44e193a7
5
5
  SHA512:
6
- metadata.gz: 6424048a8a71b877fe32a3ed0278b79391f04cfea1836e09750a64aadc246f6a2df5e57560e0ff3e502b78b26a286843636b18520f346c7add1afe85bfe6e9fe
7
- data.tar.gz: 9091b37b0f6ef280c1927b32299886318f401fbaa0c9c90da2a70d0542351ab67190e2bc9ea5f946de7557c03d279cf2983eb9cd8a75ba2e70ab0062e4c4ba68
6
+ metadata.gz: 80ff25b583304c98bd7fac3b838b901010d6d8a44142c9f8cc5a73d69a86c36d5aed47ab9426875fa7d7d8d8036c35b95fb9520e1aae2c91b4589cdd77df4220
7
+ data.tar.gz: 7bf0cf0736dea5c94427049d48a7693e19bc2a6230055a78b759ee12e5df3fcca7282c5ce763c3d2de91bdf31c7fee52e83939bb45ca616a21cd868d85e9d9eb
data/CHANGELOG.md CHANGED
@@ -1,3 +1,5 @@
1
+ ### 0.2.0
2
+
1
3
  ### 0.0.1 / 2024-09-11
2
4
 
3
5
  * Everything is new. First release.
data/Manifest.txt CHANGED
@@ -6,7 +6,11 @@ config/timezones_africa.csv
6
6
  config/timezones_america.csv
7
7
  config/timezones_asia.csv
8
8
  config/timezones_europe.csv
9
+ config/timezones_middle_east.csv
10
+ config/timezones_pacific.csv
9
11
  config/timezones_world.csv
10
12
  lib/football-timezones.rb
13
+ lib/football-timezones/datasets.rb
14
+ lib/football-timezones/timezones.rb
11
15
  lib/football-timezones/version.rb
12
16
  lib/football/timezones.rb
@@ -1,4 +1,17 @@
1
1
  key, zone
2
2
 
3
- eg, Africa/Cairo # +3 (gmt+3)
3
+ eg, Africa/Cairo
4
+
5
+ dz, Africa/Algiers
6
+
7
+ ma, Africa/Casablanca
8
+
9
+ za, Africa/Johannesburg
10
+
11
+
12
+ ng, Africa/Lagos
13
+
14
+ ke, Africa/Nairobi
15
+
16
+
4
17
 
@@ -1,29 +1,30 @@
1
1
  key, zone
2
2
 
3
3
 
4
- us, America/New_York # (gmt-5) new york
4
+ us, America/New_York
5
5
  ca, America/Toronto
6
6
 
7
7
  mx, America/Mexico_City
8
8
 
9
9
 
10
- cr, America/Costa_Rica # gmt-6
11
- gt, America/Guatemala # gmt-6
12
- hn, America/Tegucigalpa # gmt-6
13
- sv, America/El_Salvador # gmt-6
14
- ni, America/Managua # gmt-6
10
+ cr, America/Costa_Rica
11
+ gt, America/Guatemala
12
+ hn, America/Tegucigalpa
13
+ sv, America/El_Salvador
14
+ ni, America/Managua
15
15
 
16
- uy, America/Montevideo # gmt-3
17
- pe, America/Lima # gmt-5
18
- ec, America/Guayaquil # gmt-5
16
+ uy, America/Montevideo
17
+ pe, America/Lima
18
+ ec, America/Guayaquil
19
19
  co, America/Bogota
20
- bo, America/La_Paz # gmt-4
21
- cl, America/Santiago # gmt-4
20
+ bo, America/La_Paz
21
+ cl, America/Santiago
22
+ py, America/Asuncion
22
23
 
23
- br, America/Sao_Paulo # gmt-3 - change to -3?
24
- ar, America/Argentina/Buenos_Aires # gmt-3 - change to -3?
24
+ br, America/Sao_Paulo
25
+ ar, America/Argentina/Buenos_Aires
25
26
 
26
27
 
27
- concacaf.cl, America/Mexico_City ### use mx time
28
- copa.l, America/Sao_Paulo ### use brazil time
28
+ concacaf.cl, America/Mexico_City ### use mx time - why? why not?
29
+ copa.l, America/Sao_Paulo ### use brazil time - why? why not?
29
30
 
@@ -1,8 +1,8 @@
1
1
  key, zone
2
2
 
3
- jp, Asia/Tokyo # +9 (gmt+9)
3
+ jp, Asia/Tokyo
4
4
  kr, Asia/Seoul
5
- cn, Asia/Shanghai # +7 (gmt+7)
5
+ cn, Asia/Shanghai
6
6
 
7
7
 
8
8
 
@@ -9,39 +9,79 @@ de, Europe/Berlin
9
9
  fr, Europe/Paris
10
10
  it, Europe/Rome
11
11
 
12
- pt, Europe/Lisbon
12
+ sm, Europe/San_Marino
13
+ va, Europe/Vatican
13
14
 
14
15
 
16
+ pt, Europe/Lisbon
17
+ ad, Europe/Andorra
18
+ gi, Europe/Gibraltar
19
+ mc, Europe/Monaco
15
20
 
16
21
 
17
- fi, Europe/Helsinki # +2
22
+ cy, Asia/Nicosia
23
+ mt, Europe/Malta
18
24
  gr, Europe/Athens
25
+ tr, Europe/Istanbul
19
26
  ro, Europe/Bucharest
27
+ bg, Europe/Sofia
20
28
  ua, Europe/Kyiv
29
+ ru, Europe/Moscow
30
+ by, Europe/Minsk
31
+
21
32
 
22
33
 
23
- ru, Europe/Moscow
24
- tr, Europe/Istanbul # +3 turkey time/moscow time
25
34
 
26
35
  at, Europe/Vienna
27
36
  ch, Europe/Zurich
37
+ li, Europe/Vaduz
38
+
28
39
  hu, Europe/Budapest
29
40
  cz, Europe/Prague
30
41
  sk, Europe/Bratislava # link to Prague !!!
42
+ si, Europe/Ljubljana
43
+ mk, Europe/Skopje
44
+
45
+
31
46
  pl, Europe/Warsaw
47
+
32
48
  be, Europe/Brussels
33
49
  lu, Europe/Luxembourg # link to Brussels !!!
34
50
  nl, Europe/Amsterdam # link to Brussels !!!
35
51
 
36
52
 
37
- dk, Europe/Berlin ## check if country-specific available
38
- se, Europe/Berlin ## check if country-specific available
39
- hr, Europe/Belgrade ## check if country-specific available
53
+
54
+ is, Iceland
55
+
56
+
57
+ dk, Europe/Copenhagen ## link to Berlin
58
+ se, Europe/Stockholm ## link to Berlin
59
+ no, Europe/Oslo # link to Berlin
60
+ fi, Europe/Helsinki
61
+
62
+ lv, Europe/Riga
63
+ ee, Europe/Tallinn
64
+ lt, Europe/Vilnius
65
+
66
+
67
+
68
+ hr, Europe/Zagreb # link to Belgrade
69
+ al, Europe/Tirane
70
+ ba, Europe/Sarajevo # link to Belgrade
71
+ me, Europe/Podgorica
72
+
73
+
74
+
75
+ md, Europe/Chisinau
76
+
77
+
40
78
 
41
79
 
42
80
 
43
81
  ## for champs default for not to cet (central european time) - why? why not?
44
- uefa.cl, Europe/Paris
45
- uefa.el, Europe/Paris
46
- euro, Europe/Paris
82
+ uefa.cl, Europe/Paris
83
+ uefa.el, Europe/Paris
84
+ uefa.conf, Europe/Paris
85
+ uefa.nl, Europe/Paris
86
+ euro, Europe/Paris
47
87
 
@@ -0,0 +1,5 @@
1
+ key, zone
2
+
3
+ il, Asia/Jerusalem
4
+
5
+
@@ -0,0 +1,5 @@
1
+ key, zone
2
+
3
+
4
+ au, Australia/Sydney
5
+ nz, Pacific/Auckland
@@ -1,4 +1,13 @@
1
1
  key, zone
2
2
 
3
3
 
4
- ## world+2022, add quatar here
4
+ world+2022, Asia/Qatar # Qatar
5
+ world+2018, Europe/Moscow # Russia
6
+ world+2014, America/Sao_Paulo # Brazil
7
+ world+2010, Africa/Johannesburg # South Africa
8
+ world+2006, Europe/Berlin # Germany
9
+ world+2002, Asia/Tokyo # Japan & South Korea
10
+ world+1998, Europe/Paris # France
11
+
12
+
13
+
@@ -0,0 +1,48 @@
1
+
2
+
3
+ module Datasets
4
+ def self.parse_args( args )
5
+ ### split args in datasets with leagues and seasons
6
+ datasets = []
7
+ args.each do |arg|
8
+ if arg =~ %r{^[0-9/-]+$} ## season
9
+ if datasets.empty?
10
+ puts "!! ERROR - league required before season arg; sorry"
11
+ exit 1
12
+ end
13
+
14
+ season = Season.parse( arg ) ## check season
15
+ datasets[-1][1] << season
16
+ else ## assume league key
17
+ key = arg.downcase
18
+ datasets << [key, []]
19
+ end
20
+ end
21
+ datasets
22
+ end
23
+
24
+
25
+ def self.parse( txt )
26
+ ### split args in datasets with leagues and seasons
27
+ datasets = []
28
+ recs = parse_csv( txt )
29
+ recs.each do |rec|
30
+ key = rec['league'].downcase
31
+ datasets << [key, []]
32
+
33
+ seasons_str = rec['seasons']
34
+ seasons = seasons_str.split( /[ ]+/ )
35
+
36
+ seasons.each do |season_str|
37
+ season = Season.parse( season_str ) ## check season
38
+ datasets[-1][1] << season
39
+ end
40
+ end
41
+ datasets
42
+ end
43
+
44
+ def self.read( path )
45
+ parse( read_text( path ))
46
+ end
47
+ end # module Datasets
48
+
@@ -0,0 +1,154 @@
1
+ ####
2
+ ### check - nest CET class inside UTC e.g. UTC::CET - why? why not?
3
+ ## make UTC and CET into a module (not class) - why? why not?
4
+
5
+ module CET ## central european time helpers
6
+ def self.now() zone.now; end
7
+ def self.today() now.to_date; end
8
+ def self.strptime( str, format )
9
+
10
+ ### fix - change to Time.strptime - why? why not?
11
+ ## (simply) ignore offset; double check that hours, minutes
12
+ ## get parsed as is (without applying offset)
13
+
14
+ d = DateTime.strptime( str, format )
15
+ ## remove assert check - why? why not?
16
+ if d.zone != '+00:00' ### use d.offset != Ration(0,1) - why? why not?
17
+ puts "!! ASSERT - CET parse date; DateTime returns offset != +0:00"
18
+ pp d.zone
19
+ pp d
20
+ exit 1
21
+ end
22
+ zone.local_time( d.year, d.month, d.day, d.hour, d.min, d.sec )
23
+ end
24
+ def self.zone() @zone ||= UTC.find_zone( 'Europe/Vienna' ); end
25
+ end # class CET
26
+
27
+
28
+
29
+ module UTC
30
+ def self.now() Time.now.utc; end
31
+ def self.today() now.to_date; end
32
+
33
+ ## -- todo - make sure / assert it's always utc - how???
34
+ ## utc = ## tz_utc.strptime( m['utcDate'], '%Y-%m-%dT%H:%M:%SZ' )
35
+ ## note: DateTime.strptime is supposed to be unaware of timezones!!!
36
+ ## use to parse utc
37
+ ## quick hack -
38
+ ## use to_time.getutc instead of utc ???
39
+ def self.strptime( str, format )
40
+ d = DateTime.strptime( str, format )
41
+ ## remove assert check - why? why not?
42
+ if d.zone != '+00:00' ### use d.offset != Ration(0,1) - why? why not?
43
+ puts "!! ASSERT - UTC parse date; DateTime returns offset != +0:00"
44
+ pp d.zone
45
+ pp d
46
+ exit 1
47
+ end
48
+ ## note - ignores offset if any !!!!
49
+ ## todo/check - report warn if offset different from 0:00 (0/1) - why? why not?
50
+ Time.utc( d.year, d.month, d.day, d.hour, d.min, d.sec )
51
+ end
52
+
53
+ def self.find_zone( name )
54
+ zone = TZInfo::Timezone.get( name )
55
+ ## wrap tzinfo timezone in our own - for adding more (auto)checks etc.
56
+ zone ? Timezone.new( zone ) : nil
57
+ end
58
+
59
+ class Timezone ## nested inside UTC
60
+ ## todo/fix
61
+ ## cache timezone - why? why not?
62
+ def initialize( zone )
63
+ @zone = zone
64
+ end
65
+
66
+ def to_local( time )
67
+ ## assert time is Time (not Date or DateTIme)
68
+ ## and assert utc!!!
69
+ assert( time.is_a?( Time ), "time #{time} is NOT of class Time; got #{time.class.name}" )
70
+ assert( time.utc?, "time #{time} is NOT utc; utc? returns #{time.utc?}" )
71
+ local = @zone.to_local( time )
72
+ local
73
+ end
74
+
75
+ def local_time( year, month=1, mday=1, hour=0, min=0, sec=0 )
76
+ ## add auto-fix for ambigious time (dst vs non-dst)
77
+ ## always select first for now (that is, dst)
78
+ @zone.local_time( year, month, mday, hour, min, sec ) {|time| time.first }
79
+ end
80
+
81
+ def now() @zone.now; end
82
+
83
+
84
+
85
+
86
+ def assert( cond, msg )
87
+ if cond
88
+ # do nothing
89
+ else
90
+ puts "!!! assert failed - #{msg}"
91
+ exit 1
92
+ end
93
+ end
94
+ end # class Timezone
95
+ end # module UTC
96
+
97
+
98
+
99
+
100
+ module TimezoneHelper
101
+ def find_zone!( league:, season: )
102
+ ## note: do NOT pass in league struct! pass in key (string)
103
+ raise ArgumentError, "league key as string|symbol expected" unless league.is_a?(String) || league.is_a?(Symbol)
104
+
105
+ @zones ||= begin
106
+ zones = {}
107
+ ['timezones_africa',
108
+ 'timezones_america',
109
+ 'timezones_asia',
110
+ 'timezones_europe',
111
+ 'timezones_middle_east',
112
+ 'timezones_pacific',
113
+ 'timezones_world',].each do |name|
114
+ recs = read_csv( "#{SportDb::Module::Timezones.root}/config/#{name}.csv" )
115
+ recs.each do |rec|
116
+ zone = UTC.find_zone( rec['zone'] )
117
+ if zone.nil?
118
+ ## raise ArgumentError - invalid zone
119
+ puts "!! ERROR - cannot find timezone in timezone db:"
120
+ pp rec
121
+ exit 1
122
+ end
123
+ zones[ rec['key']] = zone
124
+ end
125
+ end
126
+ zones
127
+ end
128
+
129
+ ## lookup first try by league+season
130
+ league_code = league.to_s.downcase
131
+ season = Season( season )
132
+
133
+ ## e.g. world+2022, etc.
134
+ key = "#{league_code}+#{season}"
135
+ zone = @zones[key]
136
+
137
+ ## try league e.g. eng.1 etc.
138
+ zone = @zones[league_code] if zone.nil?
139
+
140
+ ## try first code only (country code )
141
+ if zone.nil?
142
+ code, _ = league_code.split( '.', 2 )
143
+ zone = @zones[code]
144
+ end
145
+
146
+ if zone.nil? ## still not found; report error
147
+ puts "!! ERROR: no timezone found for #{league} #{season}"
148
+ exit 1
149
+ end
150
+
151
+ zone
152
+ end
153
+ end # module TimezoneHelper
154
+
@@ -3,8 +3,8 @@ module SportDb
3
3
  module Module
4
4
  module Timezones
5
5
  MAJOR = 0 ## todo: namespace inside version or something - why? why not??
6
- MINOR = 0
7
- PATCH = 1
6
+ MINOR = 2
7
+ PATCH = 0
8
8
  VERSION = [MAJOR,MINOR,PATCH].join('.')
9
9
 
10
10
  def self.version
@@ -7,161 +7,24 @@ require 'tzinfo'
7
7
 
8
8
  ## our own code
9
9
  require_relative 'football-timezones/version'
10
-
10
+ require_relative 'football-timezones/timezones'
11
11
 
12
12
  ####
13
- ### check - nest CET class inside UTC e.g. UTC::CET - why? why not?
14
- ## make UTC and CET into a module (not class) - why? why not?
15
-
16
- module CET ## central european time helpers
17
- def self.now() zone.now; end
18
- def self.today() now.to_date; end
19
- def self.strptime( str, format )
20
-
21
- ### fix - change to Time.strptime - why? why not?
22
- ## (simply) ignore offset; double check that hours, minutes
23
- ## get parsed as is (without applying offset)
24
-
25
- d = DateTime.strptime( str, format )
26
- ## remove assert check - why? why not?
27
- if d.zone != '+00:00' ### use d.offset != Ration(0,1) - why? why not?
28
- puts "!! ASSERT - CET parse date; DateTime returns offset != +0:00"
29
- pp d.zone
30
- pp d
31
- exit 1
32
- end
33
- zone.local_time( d.year, d.month, d.day, d.hour, d.min, d.sec )
34
- end
35
- def self.zone() @zone ||= UTC.find_zone( 'Europe/Vienna' ); end
36
- end # class CET
37
-
38
-
39
-
40
- module UTC
41
- def self.now() Time.now.utc; end
42
- def self.today() now.to_date; end
43
-
44
- ## -- todo - make sure / assert it's always utc - how???
45
- ## utc = ## tz_utc.strptime( m['utcDate'], '%Y-%m-%dT%H:%M:%SZ' )
46
- ## note: DateTime.strptime is supposed to be unaware of timezones!!!
47
- ## use to parse utc
48
- ## quick hack -
49
- ## use to_time.getutc instead of utc ???
50
- def self.strptime( str, format )
51
- d = DateTime.strptime( str, format )
52
- ## remove assert check - why? why not?
53
- if d.zone != '+00:00' ### use d.offset != Ration(0,1) - why? why not?
54
- puts "!! ASSERT - UTC parse date; DateTime returns offset != +0:00"
55
- pp d.zone
56
- pp d
57
- exit 1
58
- end
59
- ## note - ignores offset if any !!!!
60
- ## todo/check - report warn if offset different from 0:00 (0/1) - why? why not?
61
- Time.utc( d.year, d.month, d.day, d.hour, d.min, d.sec )
62
- end
63
-
64
- def self.find_zone( name )
65
- zone = TZInfo::Timezone.get( name )
66
- ## wrap tzinfo timezone in our own - for adding more (auto)checks etc.
67
- zone ? Timezone.new( zone ) : nil
68
- end
69
-
70
- class Timezone ## nested inside UTC
71
- ## todo/fix
72
- ## cache timezone - why? why not?
73
- def initialize( zone )
74
- @zone = zone
75
- end
76
-
77
- def to_local( time )
78
- ## assert time is Time (not Date or DateTIme)
79
- ## and assert utc!!!
80
- assert( time.is_a?( Time ), "time #{time} is NOT of class Time; got #{time.class.name}" )
81
- assert( time.utc?, "time #{time} is NOT utc; utc? returns #{time.utc?}" )
82
- local = @zone.to_local( time )
83
- local
84
- end
85
-
86
- def local_time( year, month=1, mday=1, hour=0, min=0, sec=0 )
87
- @zone.local_time( year, month, mday, hour, min, sec )
88
- end
89
-
90
- def now() @zone.now; end
91
-
92
-
93
-
94
- def assert( cond, msg )
95
- if cond
96
- # do nothing
97
- else
98
- puts "!!! assert failed - #{msg}"
99
- exit 1
100
- end
101
- end
102
- end # class Timezone
103
- end # module UTC
104
-
105
-
106
-
107
-
108
- module TimezoneHelper
109
- def find_zone!( league:, season: )
110
- @zones ||= begin
111
- zones = {}
112
- ['timezones_america',
113
- 'timezones_asia',
114
- 'timezones_europe',
115
- 'timezones_world',].each do |name|
116
- recs = read_csv( "#{SportDb::Module::Timezones.root}/config/#{name}.csv" )
117
- recs.each do |rec|
118
- zone = UTC.find_zone( rec['zone'] )
119
- if zone.nil?
120
- ## raise ArgumentError - invalid zone
121
- puts "!! ERROR - cannot find timezone in timezone db:"
122
- pp rec
123
- exit 1
124
- end
125
- zones[ rec['key']] = zone
126
- end
127
- end
128
- zones
129
- end
130
-
131
- ## lookup first try by league+season
132
- league_code = league.to_s.downcase
133
- season = Season( season )
134
-
135
- ## e.g. world+2022, etc.
136
- key = "#{league_code}+#{season}"
137
- zone = @zones[key]
138
-
139
- ## try league e.g. eng.1 etc.
140
- zone = @zones[league_code] if zone.nil?
141
-
142
- ## try first code only (country code )
143
- if zone.nil?
144
- code, _ = league_code.split( '.', 2 )
145
- zone = @zones[code]
146
- end
147
-
148
- if zone.nil? ## still not found; report error
149
- puts "!! ERROR: no timezone found for #{league} #{season}"
150
- exit 1
151
- end
152
-
153
- zone
13
+ ### note - make find_zone! public/global by default - why? why not?
14
+ module Kernel
15
+ include TimezoneHelper
154
16
  end
155
- end # module TimezoneHelper
156
17
 
157
18
 
158
19
 
20
+ require_relative 'football-timezones/datasets'
21
+
22
+ ###
23
+ ### note - make read_datasets & friends public/global by default - why? why not?
24
+ def read_datasets( path ) Datasets.read( path ); end
25
+ def parse_datasets( str ) Datasets.parse( str ); end
26
+ def parse_datasets_args( args ) Datasets.parse_args( args ); end
159
27
 
160
- ####
161
- ### note - make find_zone! public/global by default - why? why not?
162
- module Kernel
163
- include TimezoneHelper
164
- end
165
28
 
166
29
 
167
30
  puts SportDb::Module::Timezones.banner ## say hello
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: football-timezones
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gerald Bauer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-09-11 00:00:00.000000000 Z
11
+ date: 2024-09-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: tzinfo
@@ -103,8 +103,12 @@ files:
103
103
  - config/timezones_america.csv
104
104
  - config/timezones_asia.csv
105
105
  - config/timezones_europe.csv
106
+ - config/timezones_middle_east.csv
107
+ - config/timezones_pacific.csv
106
108
  - config/timezones_world.csv
107
109
  - lib/football-timezones.rb
110
+ - lib/football-timezones/datasets.rb
111
+ - lib/football-timezones/timezones.rb
108
112
  - lib/football-timezones/version.rb
109
113
  - lib/football/timezones.rb
110
114
  homepage: https://github.com/sportdb/sport.db