cronex 0.7.0 → 0.8.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
  SHA1:
3
- metadata.gz: 29978d178bd1bb48a3a10583b197d09a0bd768ea
4
- data.tar.gz: 7efd313aecf280cfe7d6817b392cc51e571a7c29
3
+ metadata.gz: 1ab473d3578046b33ddd723eaca36609b34118dd
4
+ data.tar.gz: 7246cc710d1ca21a5204bb5011531f56a88b1599
5
5
  SHA512:
6
- metadata.gz: fa456bfec078001cc6b12cc6c7d950e6dd1b8746d69f7341f3ffa6a2834add6ac72ebdb96364713f9d0818eab7dd1c6e6a857cf281a88c7447b1079ac75b68b6
7
- data.tar.gz: b4dd39b0fce8599164262e26000bad29b2eeecfc964e82675f353c6af1a886cec1c7f8ba22a494e195fb5ceaa3182978de2306eff54cc73cbc5f4563e08f4bdf
6
+ metadata.gz: 6f2f55fec081a1eb1631e597c0156a7f703e56834bf83c1e82b4ada16b2def0b90117f27824066efb4e49e1a98b2a7a423fd3cf9214a47281238df1c2ab0ade8
7
+ data.tar.gz: 9c0bcdf5a8814ffc8ad7d81d3cb3e939fe2bb94e63f4f7a0284a08a6ef6791f5378a0a2c8e566cefa9d220505985d1433b16dd4852a07b595c3177664771bb00
@@ -1,3 +1,9 @@
1
1
  language: ruby
2
+
3
+ cache: bundler
4
+
2
5
  rvm:
3
- - 2.2
6
+ - 2.3
7
+ - 2.4
8
+ - 2.5
9
+ - 2.6
@@ -1,3 +1,6 @@
1
+ ### [0.8.0] - 2019-04-18
2
+ * Add support for timezones
3
+
1
4
  ### [0.7.0] - 2018-11-22
2
5
  * Include day of week when day of month is specified
3
6
 
data/README.md CHANGED
@@ -16,6 +16,7 @@ Original Author & Credit: Brady Holt (http://www.geekytidbits.com).
16
16
  * Provides casing options (sentence, title, lower)
17
17
  * Support for non-standard non-zero-based week day numbers
18
18
  * Supports printing to locale specific human readable format
19
+ * Supports displaying times in specific timezones
19
20
 
20
21
  For a quick intro to cron see Quartz [Cron Tutorial](http://www.quartz-scheduler.org/documentation/quartz-1.x/tutorials/crontrigger).
21
22
 
@@ -61,6 +62,12 @@ Or install it yourself as:
61
62
  Cronex::ExpressionDescriptor.new('30 2 * 2 1-5', {}, 'fr').description
62
63
  => À 2:30 AM, lundi à vendredi, seulement en février
63
64
 
65
+ #### Timezones
66
+
67
+ Cronex::ExpressionDescriptor.new('0-10 11 * * *', {}, 'en', 'America/Los_Angeles').description
68
+ => Every minute between 4:00 AM and 4:10 AM # PDT or
69
+ => Every minute between 3:00 AM and 3:10 AM # PST
70
+
64
71
  See spec tests for more examples.
65
72
 
66
73
  ### Contributing
@@ -20,6 +20,7 @@ Gem::Specification.new do |spec|
20
20
  spec.test_files = spec.files.grep(/^(test|spec|features)\//)
21
21
  spec.require_paths = ['lib']
22
22
 
23
+ spec.add_runtime_dependency 'tzinfo', '~> 1.2.5'
23
24
  spec.add_runtime_dependency 'unicode'
24
25
  spec.add_development_dependency 'pry', '~> 0.10'
25
26
  spec.add_development_dependency 'rake', '~> 10.1'
@@ -1,7 +1,7 @@
1
1
  module Cronex
2
2
  class HoursDescription < Description
3
- def single_item_description(expression)
4
- Cronex::Utils.format_time(expression, '0')
3
+ def single_item_description(expression, timezone = 'UTC')
4
+ Cronex::Utils.format_time(expression, '0', '', timezone)
5
5
  end
6
6
 
7
7
  def interval_description_format(expression)
@@ -16,14 +16,15 @@ module Cronex
16
16
  }
17
17
 
18
18
  class ExpressionDescriptor
19
- attr_accessor :expression, :expression_parts, :options, :parsed, :resources
19
+ attr_accessor :expression, :expression_parts, :options, :parsed, :resources, :timezone
20
20
 
21
- def initialize(expression, options = {}, locale = nil)
21
+ def initialize(expression, options = {}, locale = nil, timezone = 'UTC')
22
22
  @expression = expression
23
23
  @options = CRONEX_OPTS.merge(options)
24
24
  @expression_parts = []
25
25
  @parsed = false
26
26
  @resources = Cronex::Resource.new(locale)
27
+ @timezone = timezone
27
28
  end
28
29
 
29
30
  def to_hash
@@ -129,19 +130,19 @@ module Cronex
129
130
  description = ''
130
131
  if [sec_exp, min_exp, hour_exp].all? { |exp| !Cronex::Utils.include_any?(exp, SPECIAL_CHARS) }
131
132
  # specific time of day (i.e. 10 14)
132
- description += resources.get('at') + ' ' + Cronex::Utils.format_time(hour_exp, min_exp, sec_exp)
133
+ description += resources.get('at') + ' ' + Cronex::Utils.format_time(hour_exp, min_exp, sec_exp, timezone)
133
134
  elsif min_exp.include?('-') && !min_exp.include?('/') && !min_exp.include?(',') && !Cronex::Utils.include_any?(hour_exp, SPECIAL_CHARS)
134
135
  # Minute range in single hour (e.g. 0-10 11)
135
136
  min_parts = min_exp.split('-')
136
137
  description += format(
137
138
  resources.get('every_minute_between'),
138
- Cronex::Utils.format_time(hour_exp, min_parts[0]),
139
- Cronex::Utils.format_time(hour_exp, min_parts[1]))
139
+ Cronex::Utils.format_time(hour_exp, min_parts[0], '', timezone),
140
+ Cronex::Utils.format_time(hour_exp, min_parts[1], '', timezone))
140
141
  elsif hour_exp.include?(',') && !Cronex::Utils.include_any?(min_exp, SPECIAL_CHARS)
141
142
  # Hours list with single minute (e.g. 30 6,14,16)
142
143
  hour_parts = hour_exp.split(',')
143
144
  description += resources.get('at')
144
- h_parts = hour_parts.map { |part| ' ' + Cronex::Utils.format_time(part, min_exp) }
145
+ h_parts = hour_parts.map { |part| ' ' + Cronex::Utils.format_time(part, min_exp, '', timezone) }
145
146
  description += h_parts[0...-1].join(',') + ' ' + resources.get('and') + h_parts.last
146
147
  else
147
148
  sec_desc = seconds_description(expression_parts)
@@ -1,3 +1,5 @@
1
+ require 'tzinfo'
2
+
1
3
  module Cronex
2
4
  module Utils
3
5
  extend self
@@ -32,18 +34,14 @@ module Cronex
32
34
  end
33
35
  end
34
36
 
35
- def format_time(hour_expression, minute_expression, second_expression = '')
37
+ def format_time(hour_expression, minute_expression, second_expression = '', timezone = 'UTC')
36
38
  hour = integer(hour_expression)
37
- period = hour >= 12 ? 'PM' : 'AM'
38
- hour -= 12 if hour > 12
39
39
  minute = integer(minute_expression)
40
- minute = format('%02d', minute)
41
- second = ''
42
- if present?(second_expression)
43
- second = integer(second_expression)
44
- second = ':' + format('%02d', second)
45
- end
46
- format('%s:%s%s %s', hour, minute, second, period)
40
+ second = second_expression.to_s.empty? ? 0 : integer(second_expression)
41
+ tz = TZInfo::Timezone.get(timezone)
42
+ time = tz.utc_to_local(Date.today.to_time + hour * 60 * 60 + minute * 60 + second)
43
+ format = present?(second_expression) ? '%l:%M:%S %p' : '%l:%M %p'
44
+ time.strftime(format).lstrip
47
45
  end
48
46
  end
49
47
  end
@@ -1,3 +1,3 @@
1
1
  module Cronex
2
- VERSION = '0.7.0'
2
+ VERSION = '0.8.0'
3
3
  end
@@ -4,8 +4,8 @@ require 'cronex'
4
4
  module Cronex
5
5
  describe ExpressionDescriptor do
6
6
 
7
- def desc(expression, opts = {})
8
- Cronex::ExpressionDescriptor.new(expression, opts, 'en').description
7
+ def desc(expression, opts = {}, timezone = 'UTC')
8
+ Cronex::ExpressionDescriptor.new(expression, opts, 'en', timezone).description
9
9
  end
10
10
 
11
11
  let(:opts) { { zero_based_dow: false } }
@@ -375,7 +375,27 @@ module Cronex
375
375
  end
376
376
 
377
377
  it 'year increments' do
378
- expect(desc('0 0 0 1 MAR * 2010/5')).to eq('At 0:00 AM, on day 1 of the month, only in March, every 5 years, starting in 2010')
378
+ expect(desc('0 0 0 1 MAR * 2010/5')).to eq('At 12:00 AM, on day 1 of the month, only in March, every 5 years, starting in 2010')
379
+ end
380
+ end
381
+
382
+ context 'timezone' do
383
+ it 'minute span' do
384
+ tz = TZInfo::Timezone.get('America/Los_Angeles')
385
+ hour = tz.period_for_local(Time.now).zone_identifier.to_s == 'PDT' ? 4 : 3
386
+ expect(desc('0-10 11 * * *', {}, 'America/Los_Angeles')).to eq("Every minute between #{hour}:00 AM and #{hour}:10 AM")
387
+ end
388
+
389
+ it 'twice a day' do
390
+ tz = TZInfo::Timezone.get('America/Los_Angeles')
391
+ hour = tz.period_for_local(Time.now).zone_identifier.to_s == 'PDT' ? 5 : 4
392
+ expect(desc('0 0,12 * * *', {}, 'America/Los_Angeles')).to eq("At #{hour}:00 PM and #{hour}:00 AM")
393
+ end
394
+
395
+ it 'ahead of GMT' do
396
+ tz = TZInfo::Timezone.get('Europe/Vienna')
397
+ hour = tz.period_for_local(Time.now).zone_identifier.to_s == 'CEST' ? 1 : 12
398
+ expect(desc('0-10 11 * * *', {}, 'Europe/Vienna')).to eq("Every minute between #{hour}:00 PM and #{hour}:10 PM")
379
399
  end
380
400
  end
381
401
  end
@@ -375,7 +375,7 @@ module Cronex
375
375
  end
376
376
 
377
377
  it 'year increments' do
378
- expect(desc('0 0 0 1 MAR * 2010/5')).to eq('À 0:00 AM, le 1 de chaque mois, seulement en mars, tous les 5 ans, commence en 2010')
378
+ expect(desc('0 0 0 1 MAR * 2010/5')).to eq('À 12:00 AM, le 1 de chaque mois, seulement en mars, tous les 5 ans, commence en 2010')
379
379
  end
380
380
  end
381
381
  end
@@ -375,7 +375,7 @@ module Cronex
375
375
  end
376
376
 
377
377
  it 'year increments' do
378
- expect(desc('0 0 0 1 MAR * 2010/5')).to eq('Às 0:00 AM, no dia 1 do mês, em março, a cada 5 anos, iniciando em 2010')
378
+ expect(desc('0 0 0 1 MAR * 2010/5')).to eq('Às 12:00 AM, no dia 1 do mês, em março, a cada 5 anos, iniciando em 2010')
379
379
  end
380
380
  end
381
381
  end
@@ -375,7 +375,7 @@ module Cronex
375
375
  end
376
376
 
377
377
  it 'year increments' do
378
- expect(desc('0 0 0 1 MAR * 2010/5')).to eq('La 0:00 AM, în a 1-a zi a lunii, numai în martie, la fiecare 5 ani, pornire în 2010')
378
+ expect(desc('0 0 0 1 MAR * 2010/5')).to eq('La 12:00 AM, în a 1-a zi a lunii, numai în martie, la fiecare 5 ani, pornire în 2010')
379
379
  end
380
380
  end
381
381
  end
@@ -375,7 +375,7 @@ module Cronex
375
375
  end
376
376
 
377
377
  it 'year increments' do
378
- expect(desc('0 0 0 1 MAR * 2010/5')).to eq('В 0:00 AM, 1 число месяца, только март, каждые 5 лет, начало в 2010')
378
+ expect(desc('0 0 0 1 MAR * 2010/5')).to eq('В 12:00 AM, 1 число месяца, только март, каждые 5 лет, начало в 2010')
379
379
  end
380
380
  end
381
381
  end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cronex
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adrian Kazaku
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-11-23 00:00:00.000000000 Z
11
+ date: 2019-04-18 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: tzinfo
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 1.2.5
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 1.2.5
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: unicode
15
29
  requirement: !ruby/object:Gem::Requirement