knjrbfw 0.0.59 → 0.0.62

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.
data/lib/knj/datet.rb DELETED
@@ -1,1072 +0,0 @@
1
- require "time"
2
-
3
- #This class handels various time- and date-specific behaviour in a friendly way.
4
- #===Examples
5
- # datet = Knj::Datet.new #=> 2012-05-03 20:35:16 +0200
6
- # datet = Knj::Datet.new(Time.now) #=> 2012-05-03 20:35:16 +0200
7
- # datet.months + 5 #=> 2012-10-03 20:35:16 +0200
8
- # datet.days + 64 #=> 2012-12-06 20:35:16 +010
9
- class Knj::Datet
10
- attr_accessor :time
11
-
12
- #Initializes the object. Default is the current time. A time-object can be given.
13
- def initialize(time = Time.now, *args)
14
- if time.is_a?(Time)
15
- @time = time
16
- else
17
- begin
18
- @time = Time.new(*([time] | args))
19
- rescue ArgumentError => e
20
- days_left = 0
21
- months_left = 0
22
- hours_left = 0
23
- mins_left = 0
24
- secs_left = 0
25
- usecs_left = 0
26
-
27
- #Check larger month the allowed.
28
- if args[0] and args[0] > 12
29
- months_left = args[0] - 12
30
- args[0] = 12
31
- end
32
-
33
- #Check larger date than allowed.
34
- datet = Knj::Datet.new(time, args[0], 1)
35
- dim = datet.days_in_month
36
-
37
- if args[1] and args[1] > dim
38
- days_left = args[1] - dim
39
- args[1] = dim if days_left > 0
40
- end
41
-
42
- #Check larger hour than allowed.
43
- if args[2] and args[2] >= 24
44
- hours_left = args[2] + 1
45
- args[2] = 0
46
- end
47
-
48
- #Check larger minute than allowed.
49
- if args[3] and args[3] >= 60
50
- mins_left = args[3] + 1
51
- args[3] = 0
52
- end
53
-
54
- #Check larger secs than allowed.
55
- if args[4] and args[4] >= 60
56
- secs_left = args[4] + 1
57
- args[4] = 0
58
- end
59
-
60
- #Check larger usecs than allowed.
61
- if args[5] and args[5] >= 60
62
- usecs_left = args[5] + 1
63
- args[5] = 0
64
- end
65
-
66
- #Generate new stamp.
67
- @time = Time.new(*([time] | args))
68
- self.mins + mins_left if mins_left > 0
69
- self.hours + hours_left if hours_left > 0
70
- self.days + days_left if days_left > 0
71
- self.months + months_left if months_left > 0
72
- self.secs + secs_left if secs_left > 0
73
- self.usecs + usecs_left if usecs_left > 0
74
- end
75
- end
76
- end
77
-
78
- #Goes forward day-by-day and stops at a date matching the criteria given.
79
- #
80
- #===Examples
81
- # datet.time #=> 2012-05-03 19:36:08 +0200
82
- #
83
- #Try to find next saturday.
84
- # datet.find(:day, :day_in_week => 5) #=> 2012-05-05 19:36:08 +0200
85
- #
86
- #Try to find next wednesday by Time's wday-method.
87
- # datet.find(:day, :wday => 3) #=> 2012-05-09 19:36:08 +0200
88
- def find(incr, args)
89
- count = 0
90
- while true
91
- if args[:day_in_week] and self.day_in_week == args[:day_in_week]
92
- return self
93
- elsif args[:wday] and self.time.wday == args[:wday].to_i
94
- return self
95
- end
96
-
97
- if incr == :day
98
- self.add_days(1)
99
- elsif incr == :month
100
- self.add_months(1)
101
- else
102
- raise "Invalid increment: #{incr}."
103
- end
104
-
105
- count += 1
106
- raise "Endless loop?" if count > 999
107
- end
108
- end
109
-
110
- #Add a given amount of seconds to the object.
111
- def add_usecs(usecs = 1)
112
- usecs = usecs.to_i
113
- cur_usecs = @time.usec
114
- next_usec = cur_usecs + usecs
115
-
116
- if next_usec >= 60
117
- @time = self.add_secs(1).stamp(:datet => false, :usec => 0)
118
- usecs_left = (usecs - 1) - (60 - cur_usecs)
119
- return self.add_usecs(usecs_left) if usecs_left > 0
120
- elsif next_usec < 0
121
- @time = self.add_secs(-1).stamp(:datet => false, :usec => 59)
122
- usecs_left = usecs + cur_usecs + 1
123
- self.add_usecs(usecs_left) if usecs_left > 0
124
- else
125
- @time = self.stamp(:datet => false, :usec => next_usec)
126
- end
127
-
128
- return self
129
- end
130
-
131
- #Add a given amount of seconds to the object.
132
- def add_secs(secs = 1)
133
- secs = secs.to_i
134
- cur_secs = @time.sec
135
- next_sec = cur_secs + secs
136
-
137
- if next_sec >= 60
138
- @time = self.add_mins(1).stamp(:datet => false, :sec => 0)
139
- secs_left = (secs - 1) - (60 - cur_secs)
140
- return self.add_secs(secs_left) if secs_left > 0
141
- elsif next_sec < 0
142
- @time = self.add_mins(-1).stamp(:datet => false, :sec => 59)
143
- secs_left = secs + cur_secs + 1
144
- self.add_secs(secs_left) if secs_left > 0
145
- else
146
- @time = self.stamp(:datet => false, :sec => next_sec)
147
- end
148
-
149
- return self
150
- end
151
-
152
- #Add a given amount of minutes to the object.
153
- #===Examples
154
- # datet = Knj::Datet.new #=> 2012-05-03 17:39:45 +0200
155
- # datet.add_mins(30)
156
- # datet.time #=> 2012-05-03 18:08:45 +0200
157
- def add_mins(mins = 1)
158
- mins = mins.to_i
159
- cur_mins = @time.min
160
- next_min = cur_mins + mins
161
-
162
- if next_min >= 60
163
- @time = self.add_hours(1).stamp(:datet => false, :min => 0)
164
- mins_left = (mins - 1) - (60 - cur_mins)
165
- return self.add_mins(mins_left) if mins_left > 0
166
- elsif next_min < 0
167
- @time = self.add_hours(-1).stamp(:datet => false, :min => 59)
168
- mins_left = mins + cur_mins + 1
169
- self.add_mins(mins_left) if mins_left > 0
170
- else
171
- @time = self.stamp(:datet => false, :min => next_min)
172
- end
173
-
174
- return self
175
- end
176
-
177
- #Adds a given amount of hours to the object.
178
- #===Examples
179
- # datet = Knj::Datet.new
180
- # datet.add_hours(2)
181
- def add_hours(hours = 1)
182
- hours = hours.to_i
183
- cur_hour = @time.hour
184
- next_hour = cur_hour + hours
185
-
186
- if next_hour >= 24
187
- @time = self.add_days(1).stamp(:datet => false, :hour => 0)
188
- hours_left = (hours - 1) - (24 - cur_hour)
189
- return self.add_hours(hours_left) if hours_left > 0
190
- elsif next_hour < 0
191
- @time = self.add_days(-1).stamp(:datet => false, :hour => 23)
192
- hours_left = hours + cur_hour + 1
193
- self.add_hours(hours_left) if hours_left < 0
194
- else
195
- @time = self.stamp(:datet => false, :hour => next_hour)
196
- end
197
-
198
- return self
199
- end
200
-
201
- #Adds a given amount of days to the object.
202
- #===Examples
203
- # datet = Knj::Datet.new #=> 2012-05-03 17:42:27 +0200
204
- # datet.add_days(29)
205
- # datet.time #=> 2012-06-01 17:42:27 +0200
206
- def add_days(days = 1)
207
- days = days.to_i
208
- return self if days == 0
209
- dim = self.days_in_month
210
- cur_day = @time.day
211
- next_day = cur_day + days
212
-
213
- if next_day > dim
214
- @time = self.add_months(1).stamp(:datet => false, :day => 1)
215
- days_left = (days - 1) - (dim - cur_day)
216
- self.add_days(days_left) if days_left > 0
217
- elsif next_day <= 0
218
- self.date = 1
219
- self.add_months(-1)
220
- @time = self.stamp(:datet => false, :day => self.days_in_month)
221
- days_left = days + 1
222
- self.add_days(days_left) if days_left != 0
223
- else
224
- @time = self.stamp(:datet => false, :day => next_day)
225
- end
226
-
227
- return self
228
- end
229
-
230
- #Adds a given amount of months to the object.
231
- #===Examples
232
- # datet.time #=> 2012-06-01 17:42:27 +0200
233
- # datet.add_months(2)
234
- # datet.time #=> 2012-08-01 17:42:27 +0200
235
- def add_months(months = 1)
236
- months = months.to_i
237
- cur_month = @time.month
238
- cur_day = @time.day
239
- next_month = cur_month + months.to_i
240
-
241
- if next_month > 12
242
- @time = self.add_years(1).stamp(:datet => false, :month => 1, :day => 1)
243
- months_left = (months - 1) - (12 - cur_month)
244
- return self.add_months(months_left) if months_left > 0
245
- elsif next_month < 1
246
- @time = self.add_years(-1).stamp(:datet => false, :month => 12)
247
- else
248
- @time = self.stamp(:datet => false, :month => next_month, :day => 1)
249
- end
250
-
251
- dim = self.days_in_month
252
-
253
- if dim < cur_day
254
- @time = self.stamp(:datet => false, :day => dim)
255
- else
256
- @time = self.stamp(:datet => false, :day => cur_day)
257
- end
258
-
259
- return self
260
- end
261
-
262
- #Adds a given amount of years to the object.
263
- #===Examples
264
- # datet.time #=> 2012-08-01 17:42:27 +0200
265
- # datet.add_years(3)
266
- # datet.time #> 2014-08-01 17:42:27 +0200
267
- def add_years(years = 1)
268
- next_year = @time.year + years.to_i
269
- @time = self.stamp(:datet => false, :year => next_year)
270
- return self
271
- end
272
-
273
- #Is a year a leap year in the Gregorian calendar? Copied from Date-class.
274
- #===Examples
275
- # if Knj::Datet.gregorian_leap?(2005)
276
- # print "2005 is a gregorian-leap year."
277
- # else
278
- # print "2005 is not a gregorian-leap year."
279
- # end
280
- def self.gregorian_leap?(y)
281
- if Date.respond_to?("gregorian_leap?")
282
- return Date.gregorian_leap?(y)
283
- elsif y % 4 == 0 && y % 100 != 0
284
- return true
285
- elsif y % 400 == 0
286
- return true
287
- else
288
- return false
289
- end
290
- end
291
-
292
- #Returns the number of days in the month.
293
- #===Examples
294
- # datet = Knj::Datet.new
295
- # print "There are #{datet.days_in_month} days in the current month."
296
- def days_in_month
297
- return 29 if month == 2 and Knj::Datet.gregorian_leap?(self.year)
298
-
299
- #Thanks to ActiveSupport: http://rubydoc.info/docs/rails/2.3.8/ActiveSupport/CoreExtensions/Time/Calculations
300
- days_in_months = [nil, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
301
- return days_in_months[@time.month]
302
- end
303
-
304
- #Returns the day in the week. Monday being 1 and sunday being 6.
305
- def day_in_week
306
- diw = @time.strftime("%w").to_i
307
- if diw == 0
308
- diw = 6
309
- else
310
- diw -= 1
311
- end
312
-
313
- return diw
314
- end
315
-
316
- #Returns the days name as a string.
317
- def day_name
318
- return @time.strftime("%A")
319
- end
320
-
321
- #Returns the months name as a string.
322
- def month_name
323
- return @time.strftime("%B")
324
- end
325
-
326
- #Returns the year as an integer.
327
- def year
328
- return @time.year
329
- end
330
-
331
- #Returns the hour as an integer.
332
- def hour
333
- return @time.hour
334
- end
335
-
336
- #Returns the minute as an integer.
337
- def min
338
- return @time.min
339
- end
340
-
341
- #Returns the seconds as an integer.
342
- def sec
343
- return @time.sec
344
- end
345
-
346
- #Returns the microsecond as an integer.
347
- def usec
348
- return @time.usec
349
- end
350
-
351
- #Changes the year to the given year.
352
- # datet = Knj::Datet.now #=> 2014-05-03 17:46:11 +0200
353
- # datet.year = 2005
354
- # datet.time #=> 2005-05-03 17:46:11 +0200
355
- def year=(newyear)
356
- @time = self.stamp(:datet => false, :year => newyear)
357
- end
358
-
359
- #Returns the month as an integer.
360
- def month
361
- @mode = :months
362
- return @time.month
363
- end
364
-
365
- #Returns the day in month as an integer.
366
- def date
367
- @mode = :days
368
- return @time.day
369
- end
370
-
371
- #Returns the weekday of the week as an integer. Monday being the first and sunday being the last.
372
- def wday_mon
373
- wday = @time.wday
374
- return 0 if wday == 6
375
- return wday - 1
376
- end
377
-
378
- #Changes the date to a given date.
379
- #===Examples
380
- # datet.time #=> 2005-05-03 17:46:11 +0200
381
- # datet.date = 8
382
- # datet.time #=> 2005-05-08 17:46:11 +0200
383
- def date=(newday)
384
- newday = newday.to_i
385
-
386
- if newday <= 0
387
- self.add_days(newday - 1)
388
- else
389
- @time = self.stamp(:datet => false, :day => newday)
390
- end
391
-
392
- return self
393
- end
394
-
395
- #Changes the hour to a given new hour.
396
- #===Examples
397
- # datet.time #=> 2012-05-09 19:36:08 +0200
398
- # datet.hour = 5
399
- # datet.time #=> 2012-05-09 05:36:08 +0200
400
- def hour=(newhour)
401
- newhour = newhour.to_i
402
- day = @time.day
403
-
404
- loop do
405
- break if newhour >= 0
406
- day += -1
407
- newhour += 24
408
- end
409
-
410
- loop do
411
- break if newhour < 24
412
- day += 1
413
- newhour += -24
414
- end
415
-
416
- @time = self.stamp(:datet => false, :hour => newhour)
417
-
418
- self.date = day if day != @time.day
419
- return self
420
- end
421
-
422
- #Changes the minute to a given new minute.
423
- #===Examples
424
- # datet.time #=> 2012-05-09 05:36:08 +0200
425
- # datet.min = 35
426
- # datet.time #=> 2012-05-09 05:35:08 +0200
427
- def min=(newmin)
428
- @time = self.stamp(:datet => false, :min => newmin.to_i)
429
- end
430
-
431
- #Changes the second to a given new second.
432
- #===Examples
433
- # datet.time #=> 2012-05-09 05:35:08 +0200
434
- # datet.sec = 20
435
- # datet.time #=> 2012-05-09 05:35:20 +0200
436
- def sec=(newsec)
437
- @time = self.stamp(:datet => false, :sec => newsec.to_i)
438
- end
439
-
440
- alias :day :date
441
-
442
- #Changes the month to a given new month.
443
- #===Examples
444
- # datet.time #=> 2012-05-09 05:35:20 +0200
445
- # datet.month = 7
446
- # datet.time #=> 2012-07-09 05:35:20 +0200
447
- def month=(newmonth)
448
- @time = self.stamp(:datet => false, :month => newmonth)
449
- end
450
-
451
- #Turns the given argument into a new Time-object.
452
- #===Examples
453
- # time = Knj::Datet.arg_to_time(datet) #=> <Time>-object
454
- # time = Knj::Datet.arg_to_time(Time.now) #=> <Time>-object
455
- def self.arg_to_time(datet)
456
- if datet.is_a?(Knj::Datet)
457
- return datet.time
458
- elsif datet.is_a?(Time)
459
- return datet
460
- else
461
- raise "Could not handle object of class: '#{datet.class.name}'."
462
- end
463
- end
464
-
465
- include Comparable
466
- def <=>(timeobj)
467
- secs = Knj::Datet.arg_to_time(timeobj).to_i
468
-
469
- if secs > @time.to_i
470
- return -1
471
- elsif secs < @time.to_i
472
- return 1
473
- else
474
- return 0
475
- end
476
- end
477
-
478
- #This method is used for adding values to the object based on the current set mode.
479
- #===Examples
480
- #Add two months to the datet.
481
- # datet.months
482
- # datet.add_something(2)
483
- def add_something(val)
484
- val = -val if @addmode == "-"
485
- return self.add_years(val) if @mode == :years
486
- return self.add_hours(val) if @mode == :hours
487
- return self.add_days(val) if @mode == :days
488
- return self.add_months(val) if @mode == :months
489
- return self.add_mins(val) if @mode == :mins
490
- return self.add_secs(val) if @mode == :secs
491
- return self.add_usecs(val) if @mode == :usecs
492
- raise "No such mode: #{@mode}"
493
- end
494
-
495
- #Minus something.
496
- #===Examples
497
- # datet.months - 5
498
- # datet.years - 2
499
- def -(val)
500
- @addmode = "-"
501
- self.add_something(val)
502
- end
503
-
504
- #Add something.
505
- #===Examples
506
- # datet.months + 5
507
- # datet.months + 2
508
- def +(val)
509
- @addmode = "+"
510
- self.add_something(val)
511
- end
512
-
513
- #Sets the mode to hours and gets ready to plus or minus.
514
- #===Examples
515
- # datet.time #=> 2005-05-08 17:46:11 +0200
516
- # datet.hours + 5
517
- # datet.time #=> 2005-05-08 22:46:11 +0200
518
- def hours
519
- @mode = :hours
520
- return self
521
- end
522
-
523
- #Sets the mode to minutes and gets ready to plus or minus.
524
- #===Examples
525
- # datet.time #=> 2005-05-08 22:46:11 +0200
526
- # datet.mins + 5
527
- # datet.mins #=> 2005-05-08 22:51:11 +0200
528
- def mins
529
- @mode = :mins
530
- return self
531
- end
532
-
533
- #Sets the mode to seconds and gets ready to plus or minus.
534
- def secs
535
- @mode = :secs
536
- return self
537
- end
538
-
539
- #Sets the mode to mili-seconds and gets ready to plus or minus.
540
- def usecs
541
- @mode = :usecs
542
- return self
543
- end
544
-
545
- #Sets the mode to days and gets ready to plus or minus.
546
- #===Examples
547
- # datet.time #=> 2005-05-08 22:51:11 +0200
548
- # datet.days + 26
549
- # datet.time #=> 2005-06-03 22:51:11 +0200
550
- def days
551
- @mode = :days
552
- return self
553
- end
554
-
555
- #Sets the mode to months and gets ready to plus or minus.
556
- #===Examples
557
- # datet.time #=> 2005-06-03 22:51:11 +0200
558
- # datet.months + 14
559
- # datet.time #=> 2006-08-01 22:51:11 +0200
560
- def months
561
- @mode = :months
562
- return self
563
- end
564
-
565
- #Sets the mode to years and gets ready to plus or minus.
566
- #===Examples
567
- # datet.time #=> 2006-08-01 22:51:11 +0200
568
- # datet.years + 5
569
- # datet.time #=> 2011-08-01 22:51:11 +0200
570
- def years
571
- @mode = :years
572
- return self
573
- end
574
-
575
- #Returns a new Knj::Datet- or Time-object based on the arguments.
576
- #===Examples
577
- # time = datet.stamp(:datet => false, :min => 15, :day => 5) #=> 2012-07-05 05:15:20 +0200
578
- def stamp(args)
579
- vars = {:year => @time.year, :month => @time.month, :day => @time.day, :hour => @time.hour, :min => @time.min, :sec => @time.sec, :usec => @time.usec}
580
-
581
- args.each do |key, value|
582
- vars[key.to_sym] = value.to_i if key != :datet
583
- end
584
-
585
- time = Time.local(vars[:year], vars[:month], vars[:day], vars[:hour], vars[:min], vars[:sec], vars[:usec])
586
-
587
- if !args.key?(:datet) or args[:datet]
588
- return Knj::Datet.new(time)
589
- end
590
-
591
- return time
592
- end
593
-
594
- #Returns the time as a database-valid string.
595
- #===Examples
596
- # datet.time #=> 2011-08-01 22:51:11 +0200
597
- # datet.dbstr #=> "2011-08-01 22:51:11"
598
- # datet.dbstr(:time => false) #=> "2011-08-01"
599
- def dbstr(args = {})
600
- str = "%04d" % @time.year.to_s + "-" + "%02d" % @time.month.to_s + "-" + "%02d" % @time.day.to_s
601
-
602
- if !args.key?(:time) or args[:time]
603
- str << " " + "%02d" % @time.hour.to_s + ":" + "%02d" % @time.min.to_s + ":" + "%02d" % @time.sec.to_s
604
- end
605
-
606
- return str
607
- end
608
-
609
- #Parses the date from a database-format.
610
- #===Examples
611
- # datet = Knj::Datet.from_dbstr("2011-08-01 22:51:11")
612
- # datet.time #=> 2011-08-01 22:51:11 +0200
613
- def self.from_dbstr(date_string)
614
- if date_string.is_a?(Time)
615
- return Knj::Datet.new(date_string)
616
- elsif date_string.is_a?(Date)
617
- return Knj::Datet.new(date_string.to_time)
618
- end
619
-
620
- return false if Knj::Datet.is_nullstamp?(date_string)
621
-
622
- require "#{$knjpath}autoload/parsedate"
623
- return Knj::Datet.new(Time.local(*ParseDate.parsedate(date_string.to_s)))
624
- end
625
-
626
- #Alias for 'from_dbstr'.
627
- def self.parse(str)
628
- return Knj::Datet.from_dbstr(str)
629
- end
630
-
631
- #Returns true of the given stamp is a 'nullstamp'.
632
- #===Examples
633
- # Knj::Datet.is_nullstamp?("0000-00-00") #=> true
634
- # Knj::Datet.is_nullstamp?("0000-00-00 00:00:00") #=> true
635
- # Knj::Datet.is_nullstamp?("") #=> true
636
- # Knj::Datet.is_nullstamp?("1985-06-17") #=> false
637
- def self.is_nullstamp?(stamp)
638
- return true if !stamp or stamp == "0000-00-00" or stamp == "0000-00-00 00:00:00" or stamp.to_s.strip == ""
639
- return false
640
- end
641
-
642
- #Returns the day of the year (0-365) as an integer.
643
- #===Examples
644
- # Knj::Datet.new.day_of_year #=> 123
645
- def day_of_year
646
- return @time.strftime("%j").to_i
647
- end
648
-
649
- #Returns the day as a localized string.
650
- #===Examples
651
- # Knj::Datet.new.day_str #=> "Monday"
652
- # Knj::Datet.new.day_str(:short => true) #=> "Mon"
653
- def day_str(args = nil)
654
- ret = Knj::Datet.days_arr[@time.strftime("%w").to_i]
655
- if args.is_a?(Hash) and args[:short]
656
- ret = ret.slice(0, 3)
657
- end
658
-
659
- return ret
660
- end
661
-
662
- #Returns how many days there is between the two timestamps given as an integer.
663
- #===Examples
664
- # d1 = Knj::Datet.new #=> 2012-05-03 18:04:12 +0200
665
- # d2 = Knj::Datet.new #=> 2012-05-03 18:04:16 +0200
666
- # d2.months + 5 #=> 2012-10-03 18:04:16 +0200
667
- # Knj::Datet.days_between(d1, d2) #=> 153
668
- def self.days_between(t1, t2)
669
- raise "Timestamp 2 should be larger than timestamp 1." if t2 < t1
670
-
671
- doy1 = t1.day_of_year
672
- doy2 = t2.day_of_year
673
-
674
- yot1 = t1.year
675
- yot2 = t2.year
676
-
677
- if yot1 == yot2
678
- days_between = doy2 - doy1
679
- return days_between
680
- end
681
-
682
- upto = 365 - doy1
683
- after = doy2
684
-
685
- return upto + after
686
- end
687
-
688
- #Returns a string based on the date and time.
689
- #===Examples
690
- # datet.out #=> "03/05 2012 - 18:04"
691
- # datet.out(:time => false) #=> "03/05 2012"
692
- # datet.out(:date => false) #=> "18:04"
693
- def out(args = {})
694
- str = ""
695
- date_shown = false
696
- time_shown = false
697
-
698
- if !args.key?(:date) or args[:date]
699
- date_shown = true
700
- str << "%02d" % @time.day.to_s + "/" + "%02d" % @time.month.to_s
701
-
702
- if !args.key?(:year) or args[:year]
703
- str << " " + "%04d" % @time.year.to_s
704
- end
705
- end
706
-
707
- if !args.key?(:time) or args[:time]
708
- show_time = true
709
-
710
- if args.key?(:zerotime) and !args[:zerotime]
711
- if @time.hour == 0 and @time.min == 0
712
- show_time = false
713
- end
714
- end
715
-
716
- if show_time
717
- time_shown = true
718
- str << " - " if date_shown
719
- str << "%02d" % @time.hour.to_s + ":" + "%02d" % @time.min.to_s
720
- end
721
- end
722
-
723
- return str
724
- end
725
-
726
- #Parses various objects into Knj::Datet-objects.
727
- #===Examples
728
- # datet = Knj::Datet.in("1985-06-17") #=> 1985-06-17 00:00:00 +0200
729
- # datet = Knj::Datet.in("1985-06-17 10:00:00") #=> 1985-06-17 10:00:00 +0200
730
- # datet = Knj::Datet.in("17/06 1985 10:00") #=> 1985-06-17 10:00:00 +0200
731
- def self.in(timestr)
732
- if timestr.is_a?(Time)
733
- return Knj::Datet.new(timestr)
734
- elsif timestr.is_a?(Date)
735
- return Knj::Datet.new(timestr.to_time)
736
- elsif timestr.is_a?(Knj::Datet)
737
- return timestr
738
- elsif timestr == nil
739
- return Knj::Datet.in("1970-01-01")
740
- end
741
-
742
- if match = timestr.to_s.match(/^(\d+)\/(\d+) (\d+)/)
743
- #MySQL date format
744
- timestr = timestr.gsub(match[0], "")
745
- date = match[1]
746
- month = match[2]
747
- year = match[3]
748
-
749
- if match = timestr.match(/\s*(\d+):(\d+)/)
750
- #MySQL datetime format
751
- timestr = timestr.gsub(match[0], "")
752
- hour = match[1]
753
- minute = match[2]
754
- end
755
-
756
- return Knj::Datet.new(Time.local(year, month, date, hour, minute))
757
- elsif match = timestr.to_s.match(/^(\d{1,2})\/(\d{1,2})\/(\d{4})$/)
758
- return Knj::Datet.new(Time.local(match[3], match[2], match[1]))
759
- elsif match = timestr.to_s.match(/^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(\d{5,6})$/)
760
- #Datet.code format
761
- return Knj::Datet.new(Time.local(match[1], match[2], match[3], match[4], match[5], match[6], match[7]))
762
- 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}))$/)
763
- #Database date format (with possibility of .0 in the end - microseconds? -knj.
764
-
765
- if match[11] and match[13] and match[14]
766
- if match[12] == "+" or match[12] == "-"
767
- sign = match[12]
768
- else
769
- sign = "+"
770
- end
771
-
772
- utc_str = "#{sign}#{match[13]}:#{match[14]}"
773
- elsif match[8]
774
- utc_str = match[8].to_i
775
- else
776
- utc_str = nil
777
- end
778
-
779
- 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)
780
- return Knj::Datet.new(time)
781
- 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*)$/)
782
- 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)
783
- return Knj::Datet.new(time)
784
- end
785
-
786
- raise Knj::Errors::InvalidData.new("Wrong format: '#{timestr}', class: '#{timestr.class.name}'")
787
- end
788
-
789
- #Returns a hash with the month-no as key and month-name as value. It uses the method "_" to translate the months names. So GetText or another method has to be defined.
790
- def self.months_arr(args = {})
791
- ret = {
792
- 1 => _("January"),
793
- 2 => _("February"),
794
- 3 => _("March"),
795
- 4 => _("April"),
796
- 5 => _("May"),
797
- 6 => _("June"),
798
- 7 => _("July"),
799
- 8 => _("August"),
800
- 9 => _("September"),
801
- 10 => _("October"),
802
- 11 => _("November"),
803
- 12 => _("December")
804
- }
805
-
806
- if args["short"]
807
- ret_short = {}
808
- ret.each do |key, val|
809
- ret_short[key] = val[0..2]
810
- end
811
-
812
- return ret_short
813
- end
814
-
815
- return ret
816
- end
817
-
818
- #Returns a hash with the day-number as value (starting with 1 for monday). It uses the method "_" to translate the months names.
819
- def self.days_arr(args = {})
820
- ret = {
821
- 1 => _("Monday"),
822
- 2 => _("Tuesday"),
823
- 3 => _("Wednesday"),
824
- 4 => _("Thursday"),
825
- 5 => _("Friday"),
826
- 6 => _("Saturday"),
827
- 0 => _("Sunday")
828
- }
829
-
830
- if args["short"]
831
- ret_short = {}
832
- ret.each do |key, val|
833
- ret_short[key] = val[0..2]
834
- end
835
-
836
- return ret_short
837
- end
838
-
839
- return ret
840
- end
841
-
842
- #Returns the month-number for a given string (starting with 1 for january).
843
- #===Examples
844
- # Knj::Datet.month_str_to_no("JaNuArY") #=> 1
845
- # Knj::Datet.month_str_to_no("DECEMBER") #=> 12
846
- # Knj::Datet.month_str_to_no("kasper") #=> <Error>-raised
847
- def self.month_str_to_no(str)
848
- ret = {
849
- "jan" => 1,
850
- "january" => 1,
851
- "feb" => 2,
852
- "february" => 2,
853
- "mar" => 3,
854
- "march" => 3,
855
- "apr" => 4,
856
- "april" => 4,
857
- "may" => 5,
858
- "jun" => 6,
859
- "june" => 6,
860
- "jul" => 7,
861
- "july" => 7,
862
- "aug" => 8,
863
- "august" => 8,
864
- "sep" => 9,
865
- "september" => 9,
866
- "oct" => 10,
867
- "october" => 11,
868
- "nov" => 11,
869
- "november" => 11,
870
- "dec" => 12,
871
- "december" => 12
872
- }
873
-
874
- str = str.to_s.downcase.strip
875
- return ret[str] if ret.key?(str)
876
- raise "No month to return from that string: '#{str}'."
877
- end
878
-
879
- def loc_wday
880
- return _(@time.strftime("%A"))
881
- end
882
-
883
- def loc_wday_small
884
- return _(@time.strftime("%a"))
885
- end
886
-
887
- def loc_month
888
- return _(@time.strftime("%B"))
889
- end
890
-
891
- def to_s
892
- return @time.to_s
893
- end
894
-
895
- #This returns a code-string that can be used to recreate the Knj::Datet-object.
896
- #===Examples
897
- # code = datet.code #=> "1985061710000000000"
898
- # newdatet = Knj::Datet.in(code) #=> 1985-06-17 10:00:00 +0200
899
- def code
900
- return "#{"%04d" % @time.year}#{"%02d" % @time.month}#{"%02d" % @time.day}#{"%02d" % @time.hour}#{"%02d" % @time.min}#{"%02d" % @time.sec}#{"%05d" % @time.usec}"
901
- end
902
-
903
- #Returns the unix timestamp for this object.
904
- #===Examples
905
- # datet.unixt #=> 487843200
906
- # datet.to_i #=> 487843200
907
- def unixt
908
- return @time.to_i
909
- end
910
-
911
- alias :to_i :unixt
912
-
913
- #Returns the HTTP-date that can be used in headers and such.
914
- #===Examples
915
- # datet.httpdate #=> "Mon, 17 Jun 1985 08:00:00 GMT"
916
- def httpdate
917
- require "time"
918
- return @time.httpdate
919
- end
920
-
921
- #Returns various information about the offset as a hash.
922
- #===Examples
923
- # datet.time #=> 1985-06-17 10:00:00 +0200
924
- # datet.offset_info #=> {:sign=>"+", :hours=>2, :mins=>0, :secs=>0}
925
- def offset_info
926
- offset_secs = @time.gmt_offset
927
-
928
- offset_hours = (offset_secs.to_f / 3600.0).floor
929
- offset_secs -= offset_hours * 3600
930
-
931
- offset_minutes = (offset_secs.to_f / 60.0).floor
932
- offset_secs -= offset_minutes * 60
933
-
934
- if offset_hours > 0
935
- sign = "+"
936
- else
937
- sign = ""
938
- end
939
-
940
- return {
941
- :sign => sign,
942
- :hours => offset_hours,
943
- :mins => offset_minutes,
944
- :secs => offset_secs
945
- }
946
- end
947
-
948
- #Returns the offset as a string.
949
- #===Examples
950
- # datet.offset_str #=> "+0200"
951
- def offset_str
952
- offset_info_data = self.offset_info
953
- return "#{offset_info_data[:sign]}#{"%02d" % offset_info_data[:hours]}#{"%02d" % offset_info_data[:mins]}"
954
- end
955
-
956
- #Returns 'localtime' as of 1.9 - even in 1.8 which does it different.
957
- #===Examples
958
- # datet.localtime_str #=> "1985-06-17 10:00:00 +0200"
959
- def localtime_str
960
- return "#{"%04d" % @time.year}-#{"%02d" % @time.month}-#{"%02d" % @time.day} #{"%02d" % @time.hour}:#{"%02d" % @time.min}:#{"%02d" % @time.sec} #{self.offset_str}"
961
- end
962
-
963
- #Returns a human readable string based on the difference from the current time and date.
964
- #===Examples
965
- # datet.time #=> 1985-06-17 10:00:00 +0200
966
- # datet.ago_str #=> "27 years ago"
967
- # datet = Knj::Datet.new #=> 2012-05-03 20:31:58 +0200
968
- # datet.ago_str #=> "18 seconds ago"
969
- def ago_str(args = {})
970
- args = {
971
- :year_ago_str => "%s year ago",
972
- :years_ago_str => "%s years ago",
973
- :month_ago_str => "%s month ago",
974
- :months_ago_str => "%s months ago",
975
- :day_ago_str => "%s day ago",
976
- :days_ago_str => "%s days ago",
977
- :hour_ago_str => "%s hour ago",
978
- :hours_ago_str => "%s hours ago",
979
- :min_ago_str => "%s minute ago",
980
- :mins_ago_str => "%s minutes ago",
981
- :sec_ago_str => "%s second ago",
982
- :secs_ago_str => "%s seconds ago",
983
- :right_now_str => "right now"
984
- }.merge(args)
985
-
986
- secs_ago = Time.now.to_i - @time.to_i
987
- mins_ago = secs_ago.to_f / 60.0
988
- hours_ago = mins_ago / 60.0
989
- days_ago = hours_ago / 24.0
990
- months_ago = days_ago / 30.0
991
- years_ago = months_ago / 12.0
992
-
993
- if years_ago > 0.9 and years_ago < 1.5
994
- return sprintf(args[:year_ago_str], years_ago.to_i)
995
- elsif years_ago >= 1.5
996
- return sprintf(args[:years_ago_str], years_ago.to_i)
997
- elsif months_ago > 0.9 and months_ago < 1.5
998
- return sprintf(args[:month_ago_str], months_ago.to_i)
999
- elsif months_ago >= 1.5
1000
- return sprintf(args[:months_ago_str], months_ago.to_i)
1001
- elsif days_ago > 0.9 and days_ago < 1.5
1002
- return sprintf(args[:day_ago_str], days_ago.to_i)
1003
- elsif days_ago >= 1.5
1004
- return sprintf(args[:days_ago_str], days_ago.to_i)
1005
- elsif hours_ago > 0.9 and hours_ago < 1.5
1006
- return sprintf(args[:hour_ago_str], hours_ago.to_i)
1007
- elsif hours_ago >= 1.5
1008
- return sprintf(args[:hours_ago_str], hours_ago.to_i)
1009
- elsif mins_ago > 0.9 and mins_ago < 1.5
1010
- return sprintf(args[:min_ago_str], mins_ago.to_i)
1011
- elsif mins_ago >= 1.5
1012
- return sprintf(args[:mins_ago_str], mins_ago.to_i)
1013
- elsif secs_ago >= 0.1 and secs_ago < 1.5
1014
- return sprintf(args[:sec_ago_str], secs_ago.to_i)
1015
- elsif secs_ago >= 1.5
1016
- return sprintf(args[:secs_ago_str], secs_ago.to_i)
1017
- end
1018
-
1019
- return args[:right_now_str]
1020
- end
1021
-
1022
- #Returns the object as a human understandable string.
1023
- #===Examples
1024
- # datet.time #=> 2012-05-03 20:31:58 +0200
1025
- # datet.human_str #=> "20:31"
1026
- def human_str(args = {})
1027
- args = {
1028
- :time => true,
1029
- :number_endings => {
1030
- 0 => "th",
1031
- 1 => "st",
1032
- 2 => "nd",
1033
- 3 => "rd",
1034
- 4 => "th",
1035
- 5 => "th",
1036
- 6 => "th",
1037
- 7 => "th",
1038
- 8 => "th",
1039
- 9 => "th"
1040
- }
1041
- }.merge(args)
1042
-
1043
- now = Time.now
1044
-
1045
- #Generate normal string.
1046
- date_str = ""
1047
-
1048
- if now.day != @time.day and now.month == @time.month and now.year == @time.year
1049
- last_digit = @time.day.to_s[-1, 1].to_i
1050
-
1051
- if ending = args[:number_endings][last_digit]
1052
- #ignore.
1053
- else
1054
- ending = "."
1055
- end
1056
-
1057
- date_str << "#{@time.day}#{ending} "
1058
- elsif now.day != @time.day or now.month != @time.month or now.year != @time.year
1059
- date_str << "#{@time.day}/#{@time.month} "
1060
- end
1061
-
1062
- if now.year != @time.year
1063
- date_str << "#{@time.year} "
1064
- end
1065
-
1066
- if args[:time]
1067
- date_str << "#{@time.hour}:#{"%02d" % @time.min}"
1068
- end
1069
-
1070
- return date_str
1071
- end
1072
- end