unix_epoch 0.1.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.
data/README.rdoc ADDED
@@ -0,0 +1,54 @@
1
+ = unix_epoch
2
+
3
+ * http://github.com/chetan/unix_epoch
4
+
5
+ == DESCRIPTION:
6
+
7
+ Ruby library that adds the following methods to the DateTime class for handling
8
+ Unix timestamps.
9
+
10
+ * from_unix_ts(unix_ts, offset)
11
+ * to_unix_ts()
12
+ * to_i()
13
+
14
+ One advantage of using this library over Time.at() is the correct handling of
15
+ very large dates (> 2038) on 32-bit systems.
16
+
17
+ == DOCUMENTATION:
18
+
19
+ Documentation is available online at at rdoc.info[http://rdoc.info/projects/chetan/unix_epoch]
20
+
21
+ == SYNOPSIS:
22
+
23
+ require "unix_epoch"
24
+ dt = DateTime.from_unix_ts(1301103992)
25
+ dt.to_i == 1301103992
26
+
27
+ == INSTALL:
28
+
29
+ sudo gem install unix_epoch
30
+
31
+ == LICENSE:
32
+
33
+ (The MIT License)
34
+
35
+ Copyright (c) 2011 Pixelcop Research, Inc.
36
+
37
+ Permission is hereby granted, free of charge, to any person obtaining
38
+ a copy of this software and associated documentation files (the
39
+ 'Software'), to deal in the Software without restriction, including
40
+ without limitation the rights to use, copy, modify, merge, publish,
41
+ distribute, sublicense, and/or sell copies of the Software, and to
42
+ permit persons to whom the Software is furnished to do so, subject to
43
+ the following conditions:
44
+
45
+ The above copyright notice and this permission notice shall be
46
+ included in all copies or substantial portions of the Software.
47
+
48
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
49
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
50
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
51
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
52
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
53
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
54
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,30 @@
1
+
2
+ begin
3
+ require 'rubygems'
4
+ require 'jeweler'
5
+ Jeweler::Tasks.new do |gemspec|
6
+ gemspec.name = "unix_epoch"
7
+ gemspec.summary = "Adds methods to DateTime for dealing with Unix Timestamps"
8
+ gemspec.description = "Adds from_unix_ts and to_unix_ts methods to the DateTime class"
9
+ gemspec.email = "chetan@pixelcop.net"
10
+ gemspec.homepage = "http://github.com/chetan/unix_epoch"
11
+ gemspec.authors = ["Chetan Sarva"]
12
+ end
13
+ Jeweler::GemcutterTasks.new
14
+ rescue LoadError
15
+ puts "Jeweler not available. Install it with: sudo gem install jeweler"
16
+ end
17
+
18
+ require "rake/testtask"
19
+ desc "Run unit tests"
20
+ Rake::TestTask.new("test") { |t|
21
+ #t.libs << "test"
22
+ t.ruby_opts << "-rubygems"
23
+ t.pattern = "test/**/*_test.rb"
24
+ t.verbose = false
25
+ t.warning = false
26
+ }
27
+
28
+ require "yard"
29
+ YARD::Rake::YardocTask.new("docs") do |t|
30
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
data/lib/unix_epoch.rb ADDED
@@ -0,0 +1,125 @@
1
+
2
+ # concept borrowed from Perl's DateTime::Format::Epoch on CPAN
3
+ # instead of Rata Die (RD), we use Julian Date (JD), which is
4
+ # better understood by Ruby's DateTime library
5
+
6
+ require 'date'
7
+
8
+ module UnixEpoch
9
+
10
+ module ClassMethods
11
+
12
+ # Create a new DateTime object from a given Unix Timestamp
13
+ #
14
+ # @param [Fixnum, Bignum] unix_ts seconds since unix epoch (1970-01-01 00:00:00 UTC)
15
+ # @param [Fixnum] offset offset in seconds from UTC time
16
+ # @return [DateTime] DateTime object representation of the given Unix TS
17
+ def from_unix_ts(unix_ts, offset = 0)
18
+
19
+ # step 1) get the delta in days, seconds and nano seconds represented by unix_ts
20
+
21
+ delta_days = UnixEpoch._floor(unix_ts / 86_400)
22
+ unix_ts -= delta_days * 86_400
23
+
24
+ # unix_ts cannot be negative now, so to_i instead of _floor()
25
+ delta_secs = unix_ts.to_i
26
+ unix_ts -= delta_secs
27
+
28
+ delta_nano = unix_ts / 1e9
29
+
30
+ # step 2) add these deltas to the jd day and jd sec representation of the unix epoch
31
+
32
+ epoch_jd = UnixEpoch.jd_unix_epoch()
33
+
34
+ epoch_jd_days = epoch_jd.to_i
35
+ epoch_secs = UnixEpoch.get_jd_secs(epoch_jd) # get left over seconds from our epoch
36
+
37
+ jd_days = epoch_jd_days + delta_days
38
+
39
+ secs = epoch_secs + delta_secs + offset # add tz offset back in also
40
+ jd_secs = UnixEpoch.secs_to_jd_secs(secs) + Rational(delta_nano.round, 86_400_000_000)
41
+
42
+ return DateTime.from_jd(jd_days, jd_secs, offset)
43
+ end
44
+
45
+ end
46
+
47
+ module InstanceMethods
48
+
49
+ # Converts the current Date & Time into a Fixnum or Bignum representing
50
+ # the Unix Timestamp
51
+ #
52
+ # @return [Fixnum, Bignum] unix timestamp
53
+ def to_unix_ts
54
+ delta_days = self.jd - UnixEpoch.jd_unix_epoch()
55
+ unix_ts = delta_days * 86_400
56
+ h, m, s = self.class.day_fraction_to_time(day_fraction)
57
+ delta_secs = h * 3600 + m * 60 + s
58
+ delta_secs -= UnixEpoch.jd_fr_to_secs(offset) if offset != 0 # remove tz offset to get back to UTC
59
+ unix_ts += delta_secs
60
+ end
61
+
62
+ # (see #to_unix_ts)
63
+ def to_i
64
+ self.to_unix_ts
65
+ end
66
+
67
+ end
68
+
69
+
70
+ private
71
+
72
+ # Returns a Julian Date representing the Unix Epoch (January 1, 1970 00:00:00 UTC)
73
+ #
74
+ # @return [Fixnum] Julian Date representing the Unix Epoch
75
+ def self.jd_unix_epoch
76
+ Date.civil(1970, 1, 1).jd
77
+ end
78
+
79
+ # Convert the given number of seconds into a JD fraction
80
+ #
81
+ # @return [Rational] JD fraction representing the time
82
+ def self.secs_to_jd_secs(secs)
83
+ Rational(secs, 86_400)
84
+ end
85
+
86
+ # Retrieve the seconds part of the given Julian Date
87
+ #
88
+ # @param [Float] Julian Date including fractional value (e.g., 2455647.543)
89
+ # @return [Fixnum] Number of seconds represented by the fractional value
90
+ def self.get_jd_secs(jd)
91
+ jd_fr_to_secs(jd % 1)
92
+ end
93
+
94
+ # Convert the given Julian Date fractional value into seconds
95
+ #
96
+ # @param [Float] Julian Date fractional value (e.g., 0.543)
97
+ # @return [Fixnum] Number of seconds represented by the fractional value
98
+ def self.jd_fr_to_secs(fr)
99
+ h, m, s = DateTime.day_fraction_to_time(fr)
100
+ (h * 3600 + m * 60 + s)
101
+ end
102
+
103
+ def self._floor(x)
104
+ ix = x.to_i
105
+ if ix <= x then
106
+ return ix
107
+ end
108
+ return ix - 1
109
+ end
110
+
111
+ end
112
+
113
+ class DateTime
114
+
115
+ extend UnixEpoch::ClassMethods
116
+ include UnixEpoch::InstanceMethods
117
+
118
+ # Create a new DateTime object from a given JD
119
+ #
120
+ # +sg+ specifies the Day of Calendar Reform.
121
+ def self.from_jd(jd, fr, of = 0, sg=ITALY)
122
+ of = Rational(of, 86_400) if of != 0 and not of.kind_of? Rational
123
+ new!(jd_to_ajd(jd, fr, of), of, sg)
124
+ end
125
+ end
@@ -0,0 +1,44 @@
1
+
2
+ require 'test/unit'
3
+ require 'unix_epoch'
4
+
5
+ class UnixEpoch_Test < Test::Unit::TestCase
6
+
7
+ def setup
8
+ @f = "%Y-%m-%d %H:%M:%S"
9
+ end
10
+
11
+ def test_from_unix_ts
12
+ i = 1301103992
13
+ assert DateTime.from_unix_ts(i).strftime(@f) == Time.at(i).utc.strftime(@f)
14
+ end
15
+
16
+ def test_from_unix_ts_large_date
17
+ # date > 2038
18
+ i = 2240611200
19
+ assert DateTime.from_unix_ts(i).strftime(@f) == Time.at(i).utc.strftime(@f)
20
+ end
21
+
22
+ def test_from_unix_ts_localtime
23
+ i = 1301103992
24
+ assert DateTime.from_unix_ts(i, Time.new.utc_offset).strftime(@f) == Time.at(i).strftime(@f)
25
+ end
26
+
27
+ def test_to_unix_ts
28
+ i = 1301103992
29
+ d = DateTime.from_unix_ts(i)
30
+ t = Time.at(i)
31
+ assert d.strftime(@f) == t.utc.strftime(@f)
32
+ assert t.to_i == i
33
+ assert d.to_unix_ts == i
34
+ end
35
+
36
+ def test_to_unix_ts_localtime
37
+ i = 1301103992
38
+ d = DateTime.from_unix_ts(i, Time.new.utc_offset)
39
+ t = Time.at(i)
40
+ assert d.strftime(@f) == t.strftime(@f)
41
+ assert t.to_i == i
42
+ assert d.to_unix_ts == i
43
+ end
44
+ end
@@ -0,0 +1,43 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{unix_epoch}
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Chetan Sarva"]
12
+ s.date = %q{2011-03-26}
13
+ s.description = %q{Adds from_unix_ts and to_unix_ts methods to the DateTime class}
14
+ s.email = %q{chetan@pixelcop.net}
15
+ s.extra_rdoc_files = [
16
+ "README.rdoc"
17
+ ]
18
+ s.files = [
19
+ "README.rdoc",
20
+ "Rakefile",
21
+ "VERSION",
22
+ "lib/unix_epoch.rb",
23
+ "test/unix_epoch_test.rb",
24
+ "unix_epoch.gemspec"
25
+ ]
26
+ s.homepage = %q{http://github.com/chetan/unix_epoch}
27
+ s.require_paths = ["lib"]
28
+ s.rubygems_version = %q{1.5.0}
29
+ s.summary = %q{Adds methods to DateTime for dealing with Unix Timestamps}
30
+ s.test_files = [
31
+ "test/unix_epoch_test.rb"
32
+ ]
33
+
34
+ if s.respond_to? :specification_version then
35
+ s.specification_version = 3
36
+
37
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
38
+ else
39
+ end
40
+ else
41
+ end
42
+ end
43
+
metadata ADDED
@@ -0,0 +1,72 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: unix_epoch
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
11
+ platform: ruby
12
+ authors:
13
+ - Chetan Sarva
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-03-26 00:00:00 -04:00
19
+ default_executable:
20
+ dependencies: []
21
+
22
+ description: Adds from_unix_ts and to_unix_ts methods to the DateTime class
23
+ email: chetan@pixelcop.net
24
+ executables: []
25
+
26
+ extensions: []
27
+
28
+ extra_rdoc_files:
29
+ - README.rdoc
30
+ files:
31
+ - README.rdoc
32
+ - Rakefile
33
+ - VERSION
34
+ - lib/unix_epoch.rb
35
+ - test/unix_epoch_test.rb
36
+ - unix_epoch.gemspec
37
+ has_rdoc: true
38
+ homepage: http://github.com/chetan/unix_epoch
39
+ licenses: []
40
+
41
+ post_install_message:
42
+ rdoc_options: []
43
+
44
+ require_paths:
45
+ - lib
46
+ required_ruby_version: !ruby/object:Gem::Requirement
47
+ none: false
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ hash: 3
52
+ segments:
53
+ - 0
54
+ version: "0"
55
+ required_rubygems_version: !ruby/object:Gem::Requirement
56
+ none: false
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ hash: 3
61
+ segments:
62
+ - 0
63
+ version: "0"
64
+ requirements: []
65
+
66
+ rubyforge_project:
67
+ rubygems_version: 1.5.0
68
+ signing_key:
69
+ specification_version: 3
70
+ summary: Adds methods to DateTime for dealing with Unix Timestamps
71
+ test_files:
72
+ - test/unix_epoch_test.rb