football-timezones 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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