football-timezones 0.1.0 → 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: e08f96e81b26f14812a27466a51ac335efe52c84f2178d6401e602e27dae2d85
4
- data.tar.gz: 4d16d94cde0365e2ae50ecb0b365c5070330317ee21af883a941b1cc73c2878c
3
+ metadata.gz: d8574fc2a4c6312eb5f3080f41b1f08a353618b65f049876b2d1c90752e1f579
4
+ data.tar.gz: 001a40fbd239ab29c44104f1c67e1f033a4389974ce5699ffd9f61ce44e193a7
5
5
  SHA512:
6
- metadata.gz: a44e465c38195500850d1ec8fdae58a896f7c238d4fe146d7f263bc2ede1b58fb3b25f497d86173665e5545ea1ddeb021c954571b1b030d9c06dcca695266539
7
- data.tar.gz: d280c9f264fdb0f5dadb5b49d0cd92f925887975be4fffe24582eb00387509db240193e5adcd335ef12682b2d14026611524ac5a981b40a8617161c33d186eb1
6
+ metadata.gz: 80ff25b583304c98bd7fac3b838b901010d6d8a44142c9f8cc5a73d69a86c36d5aed47ab9426875fa7d7d8d8036c35b95fb9520e1aae2c91b4589cdd77df4220
7
+ data.tar.gz: 7bf0cf0736dea5c94427049d48a7693e19bc2a6230055a78b759ee12e5df3fcca7282c5ce763c3d2de91bdf31c7fee52e83939bb45ca616a21cd868d85e9d9eb
data/CHANGELOG.md CHANGED
@@ -1,4 +1,4 @@
1
- ### 0.1.0
1
+ ### 0.2.0
2
2
 
3
3
  ### 0.0.1 / 2024-09-11
4
4
 
data/Manifest.txt CHANGED
@@ -10,5 +10,7 @@ config/timezones_middle_east.csv
10
10
  config/timezones_pacific.csv
11
11
  config/timezones_world.csv
12
12
  lib/football-timezones.rb
13
+ lib/football-timezones/datasets.rb
14
+ lib/football-timezones/timezones.rb
13
15
  lib/football-timezones/version.rb
14
16
  lib/football/timezones.rb
@@ -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,7 +3,7 @@ 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 = 1
6
+ MINOR = 2
7
7
  PATCH = 0
8
8
  VERSION = [MAJOR,MINOR,PATCH].join('.')
9
9
 
@@ -7,170 +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
- ## add auto-fix for ambigious time (dst vs non-dst)
88
- ## always select first for now (that is, dst)
89
- @zone.local_time( year, month, mday, hour, min, sec ) {|time| time.first }
90
- end
91
-
92
- def now() @zone.now; end
93
-
94
-
95
-
96
-
97
- def assert( cond, msg )
98
- if cond
99
- # do nothing
100
- else
101
- puts "!!! assert failed - #{msg}"
102
- exit 1
103
- end
104
- end
105
- end # class Timezone
106
- end # module UTC
107
-
108
-
109
-
110
-
111
- module TimezoneHelper
112
- def find_zone!( league:, season: )
113
- ## note: do NOT pass in league struct! pass in key (string)
114
- raise ArgumentError, "league key as string|symbol expected" unless league.is_a?(String) || league.is_a?(Symbol)
115
-
116
- @zones ||= begin
117
- zones = {}
118
- ['timezones_africa',
119
- 'timezones_america',
120
- 'timezones_asia',
121
- 'timezones_europe',
122
- 'timezones_middle_east',
123
- 'timezones_pacific',
124
- 'timezones_world',].each do |name|
125
- recs = read_csv( "#{SportDb::Module::Timezones.root}/config/#{name}.csv" )
126
- recs.each do |rec|
127
- zone = UTC.find_zone( rec['zone'] )
128
- if zone.nil?
129
- ## raise ArgumentError - invalid zone
130
- puts "!! ERROR - cannot find timezone in timezone db:"
131
- pp rec
132
- exit 1
133
- end
134
- zones[ rec['key']] = zone
135
- end
136
- end
137
- zones
138
- end
139
-
140
- ## lookup first try by league+season
141
- league_code = league.to_s.downcase
142
- season = Season( season )
143
-
144
- ## e.g. world+2022, etc.
145
- key = "#{league_code}+#{season}"
146
- zone = @zones[key]
147
-
148
- ## try league e.g. eng.1 etc.
149
- zone = @zones[league_code] if zone.nil?
150
-
151
- ## try first code only (country code )
152
- if zone.nil?
153
- code, _ = league_code.split( '.', 2 )
154
- zone = @zones[code]
155
- end
156
-
157
- if zone.nil? ## still not found; report error
158
- puts "!! ERROR: no timezone found for #{league} #{season}"
159
- exit 1
160
- end
161
-
162
- zone
13
+ ### note - make find_zone! public/global by default - why? why not?
14
+ module Kernel
15
+ include TimezoneHelper
163
16
  end
164
- end # module TimezoneHelper
165
17
 
166
18
 
167
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
168
27
 
169
- ####
170
- ### note - make find_zone! public/global by default - why? why not?
171
- module Kernel
172
- include TimezoneHelper
173
- end
174
28
 
175
29
 
176
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.1.0
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-14 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
@@ -107,6 +107,8 @@ files:
107
107
  - config/timezones_pacific.csv
108
108
  - config/timezones_world.csv
109
109
  - lib/football-timezones.rb
110
+ - lib/football-timezones/datasets.rb
111
+ - lib/football-timezones/timezones.rb
110
112
  - lib/football-timezones/version.rb
111
113
  - lib/football/timezones.rb
112
114
  homepage: https://github.com/sportdb/sport.db