Class: Knj::Datet

Inherits:
Object show all
Includes:
Comparable
Defined in:
lib/knj/datet.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(time = Time.now) ⇒ Datet

Returns a new instance of Datet.



6
7
8
# File 'lib/knj/datet.rb', line 6

def initialize(time = Time.now)
  @time = time
end

Instance Attribute Details

#timeObject

Returns the value of attribute time.



4
5
6
# File 'lib/knj/datet.rb', line 4

def time
  @time
end

Class Method Details

.days_arr(args = {}) ⇒ Object



506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
# File 'lib/knj/datet.rb', line 506

def self.days_arr(args = {})
  ret = {
    1 => _("Monday"),
    2 => _("Tuesday"),
    3 => _("Wednesday"),
    4 => _("Thursday"),
    5 => _("Friday"),
    6 => _("Saturday"),
    0 => _("Sunday")
  }
  
  if args["short"]
    ret_short = {}
    ret.each do |key, val|
      ret_short[key] = val[0..2]
    end
    
    return ret_short
  end
  
  return ret
end

.days_between(t1, t2) ⇒ Object

Returns how many days there is between the two timestamps given.



366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
# File 'lib/knj/datet.rb', line 366

def self.days_between(t1, t2)
  raise "Timestamp 2 should be larger than timestamp 1." if t2 < t1
  
  doy1 = t1.day_of_year
  doy2 = t2.day_of_year
  
  yot1 = t1.year
  yot2 = t2.year
  
  if yot1 == yot2
    days_between = doy2 - doy1
    return days_between
  end
  
  upto = 365 - doy1
  after = doy2
  
  return upto + after
end

.from_dbstr(date_string) ⇒ Object



338
339
340
341
342
343
344
345
346
347
348
349
# File 'lib/knj/datet.rb', line 338

def self.from_dbstr(date_string)
  if date_string.is_a?(Time)
    return Knj::Datet.new(date_string)
  elsif date_string.is_a?(Date)
    return Knj::Datet.new(date_string.to_time)
  end
  
  return false if Knj::Datet.is_nullstamp?(date_string)
  
  require "#{$knjpath}autoload/parsedate"
  return Knj::Datet.new(Time.local(*ParseDate.parsedate(date_string.to_s)))
end

.gregorian_leap?(y) ⇒ Boolean

Is a year a leap year in the Gregorian calendar? Copied from Date-class.

Returns:

  • (Boolean)


130
131
132
133
134
135
136
137
138
139
140
# File 'lib/knj/datet.rb', line 130

def self.gregorian_leap?(y)
  if Date.respond_to?("gregorian_leap?")
    return Date.gregorian_leap?
  elsif y % 4 == 0 && y % 100 != 0
    return true
  elsif y % 400 == 0
    return true
  else
    return false
  end
end

.in(timestr) ⇒ Object



419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
# File 'lib/knj/datet.rb', line 419

def self.in(timestr)
  if timestr.is_a?(Time)
    return Knj::Datet.new(timestr)
  elsif timestr.is_a?(Date)
    return Knj::Datet.new(timestr.to_time)
  elsif timestr.is_a?(Knj::Datet)
    return timestr
  elsif timestr == nil
    return Knj::Datet.in("1970-01-01")
  end
  
  if match = timestr.to_s.match(/^(\d+)\/(\d+) (\d+)/)
    #MySQL date format
    timestr = timestr.gsub(match[0], "")
    date = match[1]
    month = match[2]
    year = match[3]
    
    if match = timestr.match(/\s*(\d+):(\d+)/)
      #MySQL datetime format
      timestr = timestr.gsub(match[0], "")
      hour = match[1]
      minute = match[2]
    end
    
    return Knj::Datet.new(Time.local(year, month, date, hour, minute))
  elsif match = timestr.to_s.match(/^(\d{1,2})\/(\d{1,2})\/(\d{4})$/)
    return Knj::Datet.new(Time.local(match[3], match[2], match[1]))
  elsif match = timestr.to_s.match(/^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(\d{5,6})$/)
    #Datet.code format
    return Knj::Datet.new(Time.local(match[1], match[2], match[3], match[4], match[5], match[6], match[7]))
  elsif match = timestr.to_s.match(/^\s*(\d{4})-(\d{1,2})-(\d{1,2})(|\s+(\d{2}):(\d{2}):(\d{2})(|\.\d+)\s*)(|\s+(UTC))(|\s+(\+|\-)(\d{2})(\d{2}))$/)
    #Database date format (with possibility of .0 in the end - miliseconds? -knj.
    
    if match[11] and match[13] and match[14]
      if match[12] == "+" or match[12] == "-"
        sign = match[12]
      else
        sign = "+"
      end
      
      utc_str = "#{sign}#{match[13]}:#{match[14]}"
    elsif match[8]
      utc_str = match[8].to_i
    else
      utc_str = nil
    end
    
    time = Time.local(match[1].to_i, match[2].to_i, match[3].to_i, match[5].to_i, match[6].to_i, match[7].to_i, utc_str)
    return Knj::Datet.new(time)
  elsif match = timestr.to_s.match(/^\s*(\d{2,4})-(\d{1,2})-(\d{1,2})(|\s+(\d{1,2}):(\d{1,2}):(\d{1,2})(:(\d{1,2})|)\s*)$/)
    time = Time.local(match[1].to_i, match[2].to_i, match[3].to_i, match[5].to_i, match[6].to_i, match[7].to_i)
    return Knj::Datet.new(time)
  end
  
  raise Knj::Errors::InvalidData.new("Wrong format: '#{timestr}', class: '#{timestr.class.name}'")
end

.is_nullstamp?(stamp) ⇒ Boolean

Returns:

  • (Boolean)


355
356
357
358
# File 'lib/knj/datet.rb', line 355

def self.is_nullstamp?(stamp)
  return true if !stamp or stamp == "0000-00-00" or stamp == "0000-00-00 00:00:00" or stamp.to_s.strip == ""
  return false
end

.month_str_to_no(str) ⇒ Object



529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
# File 'lib/knj/datet.rb', line 529

def self.month_str_to_no(str)
  ret = {
    "jan" => 1,
    "january" => 1,
    "feb" => 2,
    "february" => 2,
    "mar" => 3,
    "march" => 3,
    "apr" => 4,
    "april" => 4,
    "may" => 5,
    "jun" => 6,
    "june" => 6,
    "jul" => 7,
    "july" => 7,
    "aug" => 8,
    "august" => 8,
    "sep" => 9,
    "september" => 9,
    "oct" => 10,
    "october" => 11,
    "nov" => 11,
    "november" => 11,
    "dec" => 12,
    "december" => 12
  }
  
  str = str.to_s.downcase.strip
  return ret[str] if ret.key?(str)
  raise "No month to return from that string: '#{str}'."
end

.months_arr(args = {}) ⇒ Object

Returns a hash with the month-no as key and month-name as value.



478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
# File 'lib/knj/datet.rb', line 478

def self.months_arr(args = {})
  ret = {
    1 => _("January"),
    2 => _("February"),
    3 => _("March"),
    4 => _("April"),
    5 => _("May"),
    6 => _("June"),
    7 => _("July"),
    8 => _("August"),
    9 => _("September"),
    10 => _("October"),
    11 => _("November"),
    12 => _("December")
  }
  
  if args["short"]
    ret_short = {}
    ret.each do |key, val|
      ret_short[key] = val[0..2]
    end
    
    return ret_short
  end
  
  return ret
end

.parse(str) ⇒ Object



351
352
353
# File 'lib/knj/datet.rb', line 351

def self.parse(str)
  return Knj::Datet.from_dbstr(str)
end

Instance Method Details

#+(val) ⇒ Object



287
288
289
290
# File 'lib/knj/datet.rb', line 287

def +(val)
  @addmode = "+"
  self.add_something(val)
end

#-(val) ⇒ Object



282
283
284
285
# File 'lib/knj/datet.rb', line 282

def -(val)
  @addmode = "-"
  self.add_something(val)
end

#<=>(timeobj) ⇒ Object



261
262
263
264
265
266
267
268
269
270
271
# File 'lib/knj/datet.rb', line 261

def <=>(timeobj)
  secs = arg_to_time(timeobj).to_i
  
  if secs > @time.to_i
    return -1
  elsif secs < @time.to_i
    return 1
  else
    return 0
  end
end

#add_days(days = 1) ⇒ Object



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/knj/datet.rb', line 72

def add_days(days = 1)
  days = days.to_i
  return self if days == 0
  dim = self.days_in_month
  cur_day = @time.day
  next_day = cur_day + days
  
  if next_day > dim
    @time = self.add_months(1).stamp(:datet => false, :day => 1)
    days_left = (days - 1) - (dim - cur_day)
    self.add_days(days_left) if days_left > 0
  elsif next_day <= 0
    self.date = 1
    self.add_months(-1)
    @time = self.stamp(:datet => false, :day => self.days_in_month)
    days_left = days + 1
    self.add_days(days_left) if days_left != 0
  else
    @time = self.stamp(:datet => false, :day => next_day)
  end
  
  return self
end

#add_hours(hours = 1) ⇒ Object



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/knj/datet.rb', line 52

def add_hours(hours = 1)
  hours = hours.to_i
  cur_hour = @time.hour
  next_hour = cur_hour + hours
  
  if next_hour >= 24
    @time = self.add_days(1).stamp(:datet => false, :hour => 0)
    hours_left = (hours - 1) - (24 - cur_hour)
    return self.add_hours(hours_left) if hours_left > 0
  elsif next_hour < 0
    @time = self.add_days(-1).stamp(:datet => false, :hour => 23)
    hours_left = hours + cur_hour + 1
    self.add_hours(hours_left) if hours_left < 0
  else
    @time = self.stamp(:datet => false, :hour => next_hour)
  end
  
  return self
end

#add_mins(mins = 1) ⇒ Object



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/knj/datet.rb', line 32

def add_mins(mins = 1)
  mins = mins.to_i
  cur_mins = @time.min
  next_min  = cur_mins + mins
  
  if next_min >= 60
    @time = self.add_hours(1).stamp(:datet => false, :min => 0)
    mins_left = (mins - 1) - (60 - cur_mins)
    return self.add_mins(mins_left) if mins_left > 0
  elsif next_min < 0
    @time = self.add_hours(-1).stamp(:datet => false, :min => 59)
    mins_left = mins + cur_mins + 1
    self.add_mins(mins_left) if mins_left > 0
  else
    @time = self.stamp(:datet => false, :min => next_min)
  end
  
  return self
end

#add_months(months = 1) ⇒ Object



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/knj/datet.rb', line 96

def add_months(months = 1)
  months = months.to_i
  cur_month = @time.month
  cur_day = @time.day
  next_month = cur_month + months.to_i
  
  if next_month > 12
    @time = self.add_years(1).stamp(:datet => false, :month => 1, :day => 1)
    months_left = (months - 1) - (12 - cur_month)
    return self.add_months(months_left) if months_left > 0
  elsif next_month < 1
    @time = self.add_years(-1).stamp(:datet => false, :month => 12)
  else
    @time = self.stamp(:datet => false, :month => next_month, :day => 1)
  end
  
  dim = self.days_in_month
  
  if dim < cur_day
    @time = self.stamp(:datet => false, :day => dim)
  else
    @time = self.stamp(:datet => false, :day => cur_day)
  end
  
  return self
end

#add_something(val) ⇒ Object



273
274
275
276
277
278
279
280
# File 'lib/knj/datet.rb', line 273

def add_something(val)
  val = -val if @addmode == "-"
  return self.add_hours(val) if @mode == :hours
  return self.add_days(val) if @mode == :days
  return self.add_months(val) if @mode == :months
  return self.add_mins(val) if @mode == :mins
  raise "No such mode: #{@mode}"
end

#add_years(years = 1) ⇒ Object



123
124
125
126
127
# File 'lib/knj/datet.rb', line 123

def add_years(years = 1)
  next_year = @time.year + years.to_i
  @time = self.stamp(:datet => false, :year => next_year)
  return self
end

#arg_to_time(datet) ⇒ Object



250
251
252
253
254
255
256
257
258
# File 'lib/knj/datet.rb', line 250

def arg_to_time(datet)
  if datet.is_a?(Knj::Datet)
    return datet.time
  elsif datet.is_a?(Time)
    return datet
  else
    raise "Could not handle object of class: '#{datet.class.name}'."
  end
end

#codeObject



577
578
579
# File 'lib/knj/datet.rb', line 577

def code
  return "#{"%04d" % @time.year}#{"%02d" % @time.month}#{"%02d" % @time.day}#{"%02d" % @time.hour}#{"%02d" % @time.min}#{"%02d" % @time.sec}#{"%05d" % @time.usec}"
end

#dateObject Also known as: day



191
192
193
194
# File 'lib/knj/datet.rb', line 191

def date
  @mode = :days
  return @time.day
end

#date=(newday) ⇒ Object



202
203
204
205
206
207
208
209
210
211
212
# File 'lib/knj/datet.rb', line 202

def date=(newday)
  newday = newday.to_i
  
  if newday <= 0
    self.add_days(newday - 1)
  else
    @time = self.stamp(:datet => false, :day => newday)
  end
  
  return self
end

#day_in_weekObject



151
152
153
154
155
156
157
158
159
160
# File 'lib/knj/datet.rb', line 151

def day_in_week
  diw = @time.strftime("%w").to_i
  if diw == 0
    diw = 6
  else
    diw -= 1
  end
  
  return diw
end

#day_nameObject



162
163
164
# File 'lib/knj/datet.rb', line 162

def day_name
  return @time.strftime("%A")
end

#day_of_yearObject

Returns the day of the year (0-365).



361
362
363
# File 'lib/knj/datet.rb', line 361

def day_of_year
  return @time.strftime("%j").to_i
end

#daysObject



302
303
304
305
# File 'lib/knj/datet.rb', line 302

def days
  @mode = :days
  return self
end

#days_in_monthObject

Returns the number of days in the current month.



143
144
145
146
147
148
149
# File 'lib/knj/datet.rb', line 143

def days_in_month
  return 29 if month == 2 and Knj::Datet.gregorian_leap?(self.year)
  
  #Thanks to ActiveSupport: http://rubydoc.info/docs/rails/2.3.8/ActiveSupport/CoreExtensions/Time/Calculations
  days_in_months = [nil, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
  return days_in_months[@time.month]
end

#dbstr(args = {}) ⇒ Object



328
329
330
331
332
333
334
335
336
# File 'lib/knj/datet.rb', line 328

def dbstr(args = {})
  str = "%04d" % @time.year.to_s + "-" + "%02d" % @time.month.to_s + "-" + "%02d" % @time.day.to_s
  
  if !args.key?(:time) or args[:time]
    str << " " + "%02d" % @time.hour.to_s + ":" + "%02d" % @time.min.to_s + ":" + "%02d" % @time.sec.to_s
  end
  
  return str
end

#find(incr, args) ⇒ Object



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/knj/datet.rb', line 10

def find(incr, args)
  count = 0
  while true
    if args[:day_in_week] and self.day_in_week == args[:day_in_week]
      return self
    elsif args[:wday] and self.time.wday == args[:wday].to_i
      return self
    end
    
    if incr == :day
      self.add_days(1)
    elsif incr == :month
      self.add_months(1)
    else
      raise "Invalid increment: #{incr}."
    end
    
    count += 1
    raise "Endless loop?" if count > 999
  end
end

#hourObject



174
175
176
# File 'lib/knj/datet.rb', line 174

def hour
  return @time.hour
end

#hour=(newhour) ⇒ Object



214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
# File 'lib/knj/datet.rb', line 214

def hour=(newhour)
  newhour = newhour.to_i
  day = @time.day
  
  loop do
    break if newhour >= 0
    day += -1
    newhour += 24
  end
  
  loop do
    break if newhour < 24
    day += 1
    newhour += -24
  end
  
  @time = self.stamp(:datet => false, :hour => newhour)
  
  self.date = day if day != @time.day
  return self
end

#hoursObject



292
293
294
295
# File 'lib/knj/datet.rb', line 292

def hours
  @mode = :hours
  return self
end

#httpdateObject



587
588
589
590
# File 'lib/knj/datet.rb', line 587

def httpdate
  require "time"
  return @time.httpdate
end

#loc_monthObject



569
570
571
# File 'lib/knj/datet.rb', line 569

def loc_month
  return _(@time.strftime("%B"))
end

#loc_wdayObject



561
562
563
# File 'lib/knj/datet.rb', line 561

def loc_wday
  return _(@time.strftime("%A"))
end

#loc_wday_smallObject



565
566
567
# File 'lib/knj/datet.rb', line 565

def loc_wday_small
  return _(@time.strftime("%a"))
end

#localtime_strObject

Returns ‘localtime’ as of 1.9 - even in 1.8 which does it different.



621
622
623
# File 'lib/knj/datet.rb', line 621

def localtime_str
  return "#{"%04d" % @time.year}-#{"%02d" % @time.month}-#{"%02d" % @time.day} #{"%02d" % @time.hour}:#{"%02d" % @time.min}:#{"%02d" % @time.sec} #{self.offset_str}"
end

#minObject



178
179
180
# File 'lib/knj/datet.rb', line 178

def min
  return @time.min
end

#min=(newmin) ⇒ Object



236
237
238
# File 'lib/knj/datet.rb', line 236

def min=(newmin)
  @time = self.stamp(:datet => false, :min => newmin.to_i)
end

#minsObject



297
298
299
300
# File 'lib/knj/datet.rb', line 297

def mins
  @mode = :mins
  return self
end

#monthObject



186
187
188
189
# File 'lib/knj/datet.rb', line 186

def month
  @mode = :months
  return @time.month
end

#month=(newmonth) ⇒ Object



246
247
248
# File 'lib/knj/datet.rb', line 246

def month=(newmonth)
  @time = self.stamp(:datet => false, :month => newmonth)
end

#month_nameObject



166
167
168
# File 'lib/knj/datet.rb', line 166

def month_name
  return @time.strftime("%B")
end

#monthsObject



307
308
309
310
# File 'lib/knj/datet.rb', line 307

def months
  @mode = :months
  return self
end

#offset_infoObject



592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
# File 'lib/knj/datet.rb', line 592

def offset_info
  offset_secs = @time.gmt_offset
  
  offset_hours = (offset_secs.to_f / 3600.0).floor
  offset_secs -= offset_hours * 3600
  
  offset_minutes = (offset_secs.to_f / 60.0).floor
  offset_secs -= offset_minutes * 60
  
  if offset_hours > 0
    sign = "+"
  else
    sign = ""
  end
  
  return {
    :sign => sign,
    :hours => offset_hours,
    :mins => offset_minutes,
    :secs => offset_secs
  }
end

#offset_strObject



615
616
617
618
# File 'lib/knj/datet.rb', line 615

def offset_str
  offset_info_data = self.offset_info
  return "#{offset_info_data[:sign]}#{"%02d" % offset_info_data[:hours]}#{"%02d" % offset_info_data[:mins]}"
end

#out(args = {}) ⇒ Object



386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
# File 'lib/knj/datet.rb', line 386

def out(args = {})
  str = ""
  date_shown = false
  time_shown = false
  
  if !args.key?(:date) or args[:date]
    date_shown = true
    str << "%02d" % @time.day.to_s + "/" + "%02d" % @time.month.to_s
    
    if !args.key?(:year) or args[:year]
      str << " " + "%04d" % @time.year.to_s
    end
  end
  
  if !args.key?(:time) or args[:time]
    show_time = true
    
    if args.key?(:zerotime) and !args[:zerotime]
      if @time.hour == 0 and @time.min == 0
        show_time = false
      end
    end
    
    if show_time
      time_shown = true
      str << " - " if date_shown
      str << "%02d" % @time.hour.to_s + ":" + "%02d" % @time.min.to_s
    end
  end
  
  return str
end

#sec=(newsec) ⇒ Object



240
241
242
# File 'lib/knj/datet.rb', line 240

def sec=(newsec)
  @time = self.stamp(:datet => false, :sec => newsec.to_i)
end

#stamp(args) ⇒ Object



312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
# File 'lib/knj/datet.rb', line 312

def stamp(args)
  vars = {:year => @time.year, :month => @time.month, :day => @time.day, :hour => @time.hour, :min => @time.min, :sec => @time.sec}
  
  args.each do |key, value|
    vars[key.to_sym] = value.to_i if key != :datet
  end
  
  time = Time.local(vars[:year], vars[:month], vars[:day], vars[:hour], vars[:min], vars[:sec])
  
  if !args.key?(:datet) or args[:datet]
    return Knj::Datet.new(time)
  end
  
  return time
end

#to_sObject



573
574
575
# File 'lib/knj/datet.rb', line 573

def to_s
  return @time.to_s
end

#unixtObject Also known as: to_i



581
582
583
# File 'lib/knj/datet.rb', line 581

def unixt
  return @time.to_i
end

#wday_monObject



196
197
198
199
200
# File 'lib/knj/datet.rb', line 196

def wday_mon
  wday = @time.wday
  return 0 if wday == 6
  return wday - 1
end

#yearObject



170
171
172
# File 'lib/knj/datet.rb', line 170

def year
  return @time.year
end

#year=(newyear) ⇒ Object



182
183
184
# File 'lib/knj/datet.rb', line 182

def year=(newyear)
  @time = self.stamp(:datet => false, :year => newyear)
end