i'm working on a sticky issue: i'm converting some times based on a utc time
and longitude - the goal is the express the time as solar local time.
the code i have is close. it does something like:
DEG_PER_HR = 15.0
SECS_PER_MIN = 60.0
SECS_PER_HR = SECS_PER_MIN * 60.0
SECS_PER_DAY = SECS_PER_HR * 24
# longitudes > 180 degrees are behind UT
# longitudes <= 180 degrees are ahead of UT
offset_seconds =
if longitude > 180.0
- ((360.0 - longitude) / DEG_PER_HR) * SECS_PER_HR
else
(longitude / DEG_PER_HR) * SECS_PER_HR
end
utc + offset_seconds
this in fact yields the correct time __except__ that's it's expressed in zulu
time and not the 'local' time zone. the trick is that 'local' here means
'there' not 'here'!
in otherwords it needs to be expressed in the local
time zone of that __longitude__ not mine and not that of greenwich.
to put it more consisely i need to be able to follow
locatime_but_in_utc = utc + offset_seconds
with
move_to_zone locatime_but_in_utc, longitude
or some other viable alternative.
thoughts?
-a
···
--
to foster inner awareness, introspection, and reasoning is more efficient than
meditation and prayer.
- h.h. the 14th dali lama
i'm working on a sticky issue: i'm converting some times based on a utc time
and longitude - the goal is the express the time as solar local time.
the code i have is close. it does something like:
DEG_PER_HR = 15.0
SECS_PER_MIN = 60.0
SECS_PER_HR = SECS_PER_MIN * 60.0
SECS_PER_DAY = SECS_PER_HR * 24
# longitudes > 180 degrees are behind UT
# longitudes <= 180 degrees are ahead of UT
offset_seconds =
if longitude > 180.0
- ((360.0 - longitude) / DEG_PER_HR) * SECS_PER_HR
else
(longitude / DEG_PER_HR) * SECS_PER_HR
end
utc + offset_seconds
this in fact yields the correct time __except__ that's it's expressed in zulu
time and not the 'local' time zone. the trick is that 'local' here means
'there' not 'here'!
in otherwords it needs to be expressed in the local
time zone of that __longitude__ not mine and not that of greenwich.
to put it more consisely i need to be able to follow
locatime_but_in_utc = utc + offset_seconds
with
move_to_zone locatime_but_in_utc, longitude
or some other viable alternative.
thoughts?
Does TZInfo bring you closer?
Stolen from the README:
···
On Aug 8, 2006, at 2:23 PM, ara.t.howard@noaa.gov wrote:
Example usage
To convert a time in UTC to a local time in the America/New_York timezone, you can do the following:
require_gem 'tzinfo'
include TZInfo
tz = Timezone.get('America/New_York')
local = tz.utc_to_local(Time.utc(2005,8,29,15,35,0))
Note that the Time returned will look like it is UTC (Time.zone will return "UTC"). This is because it is not currently possible to change the offset of an individual Time instance.
-a
--
to foster inner awareness, introspection, and reasoning is more efficient than
meditation and prayer.
- h.h. the 14th dali lama
yeah - the thing is that this 'localtime' will be in utc 
-a
···
On Tue, 8 Aug 2006, Jan Svitok wrote:
Once more: what you want to achive is have function
local_solar_time(utc_time, longitude)
This is my (maybe naive) approach (It's possible I'm missing something)
To me it seems that your calculation is right,
local_solar_time = utc_time +/- offset_seconds(longitude)
+/- depends on whether longitude grows to the west (then -) or east (+)
if you want have it in local time zone, then it would be
localtime = utc_time + timezone_offset(longitude, latitude) obviously.
--
to foster inner awareness, introspection, and reasoning is more efficient than
meditation and prayer.
- h.h. the 14th dali lama
ZONES = class << Time; ZoneOffset.keys.map {|x| x.length == 1 ? x :
nil}.compact.sort; end
ZONES.unshift ZONES.pop
def move_to_zone( utc, longitude )
zone = ZONES[Integer(longitude) / Integer(DEG_PER_HR)]
utc - Time.zone_offset(zone)
end
This does not take into account daylight savings, etc. But give it a
shot and see if it's what you need.
TwP
···
On 8/8/06, ara.t.howard@noaa.gov <ara.t.howard@noaa.gov> wrote:
i'm working on a sticky issue: i'm converting some times based on a utc time
and longitude - the goal is the express the time as solar local time.
the code i have is close. it does something like:
DEG_PER_HR = 15.0
SECS_PER_MIN = 60.0
SECS_PER_HR = SECS_PER_MIN * 60.0
SECS_PER_DAY = SECS_PER_HR * 24
# longitudes > 180 degrees are behind UT
# longitudes <= 180 degrees are ahead of UT
offset_seconds =
if longitude > 180.0
- ((360.0 - longitude) / DEG_PER_HR) * SECS_PER_HR
else
(longitude / DEG_PER_HR) * SECS_PER_HR
end
utc + offset_seconds
this in fact yields the correct time __except__ that's it's expressed in zulu
time and not the 'local' time zone. the trick is that 'local' here means
'there' not 'here'!
in otherwords it needs to be expressed in the local
time zone of that __longitude__ not mine and not that of greenwich.
to put it more consisely i need to be able to follow
locatime_but_in_utc = utc + offset_seconds
with
move_to_zone locatime_but_in_utc, longitude
or some other viable alternative.
thoughts?
snip
this in fact yields the correct time __except__ that's it's expressed in zulu
time and not the 'local' time zone. the trick is that 'local' here means
'there' not 'here'!
in otherwords it needs to be expressed in the local
time zone of that __longitude__ not mine and not that of greenwich.
to put it more consisely i need to be able to follow
locatime_but_in_utc = utc + offset_seconds
with
move_to_zone locatime_but_in_utc, longitude
Clarification question ... do you want the returned value to be a
Float or an actual Time object?
TwP
PS Maybe I should have asked this before posting my little solution there 
···
On 8/8/06, ara.t.howard@noaa.gov <ara.t.howard@noaa.gov> wrote:
If I understand the problem you describe (likelihood estimate ~ 50%), it's similar to a telemetry data problem I once worked on. Here is how I handled it:
1. express the local solar time value of interest in seconds from local midnight
2. convert the UTC time stamp to seconds from UTC midnight
3. longitude shift the result of 2 to the local time frame
4. compare result of 1 and 3 to determine whether or not to process further
Maybe you could adopt a similar approach.
Regards, Morton
···
On Aug 8, 2006, at 2:23 PM, ara.t.howard@noaa.gov wrote:
i'm working on a sticky issue: i'm converting some times based on a utc time
and longitude - the goal is the express the time as solar local time.
the code i have is close. it does something like:
DEG_PER_HR = 15.0
SECS_PER_MIN = 60.0
SECS_PER_HR = SECS_PER_MIN * 60.0
SECS_PER_DAY = SECS_PER_HR * 24
# longitudes > 180 degrees are behind UT
# longitudes <= 180 degrees are ahead of UT
offset_seconds =
if longitude > 180.0
- ((360.0 - longitude) / DEG_PER_HR) * SECS_PER_HR
else
(longitude / DEG_PER_HR) * SECS_PER_HR
end
utc + offset_seconds
this in fact yields the correct time __except__ that's it's expressed in zulu
time and not the 'local' time zone. the trick is that 'local' here means
'there' not 'here'!
in otherwords it needs to be expressed in the local
time zone of that __longitude__ not mine and not that of greenwich.
to put it more consisely i need to be able to follow
locatime_but_in_utc = utc + offset_seconds
with
move_to_zone locatime_but_in_utc, longitude
or some other viable alternative.
thoughts?
-a
--
to foster inner awareness, introspection, and reasoning is more efficient than
meditation and prayer.
- h.h. the 14th dali lama
nope. timezones are politicalized solar local times. basically i'm searching
a polar orbiting satellite data set for scanlines where the localtime is about
7 am. it sounds easy - it's near impossible.
-a
···
On Wed, 9 Aug 2006, Logan Capaldo wrote:
Does TZInfo bring you closer?
Stolen from the README:
Example usage
To convert a time in UTC to a local time in the America/New_York timezone, you can do the following:
require_gem 'tzinfo'
include TZInfo
tz = Timezone.get('America/New_York')
local = tz.utc_to_local(Time.utc(2005,8,29,15,35,0))
Note that the Time returned will look like it is UTC (Time.zone will return "UTC"). This is because it is not currently possible to change the offset of an individual Time instance.
--
to foster inner awareness, introspection, and reasoning is more efficient than
meditation and prayer.
- h.h. the 14th dali lama
it's close, but check this out:
harp:~ > cat a.rb
require 'time'
class Time
ZONES =
class << self
(_ = ZoneOffset.keys.select{|z| z.size == 1}.sort).unshift(_.pop)
end
def translated longitude
zone = ZONES[Integer(longitude) / 15]
utc - Time.zone_offset(zone)
end
end
t = Time.parse('1999-12-31T23:59:59Z') or 'party like it is'
require 'yaml'
[0, 15, 16, 30, 31].each do |degrees|
y degrees => t.translated(degrees).iso8601
y -degrees => t.translated(-degrees).iso8601
end
harp:~ > ruby a.rb
0: "1999-12-31T23:59:59Z"
15: "1999-12-31T22:59:59Z"
-15: "2000-01-01T11:59:59Z"
16: "1999-12-31T22:59:59Z"
-16: "2000-01-01T10:59:59Z"
30: "1999-12-31T21:59:59Z"
-30: "2000-01-01T10:59:59Z"
31: "1999-12-31T21:59:59Z"
-31: "2000-01-01T09:59:59Z"
take one example
15: "1999-12-31T22:59:59Z"
the time is correct but the zone is not. consider, 15 degrees to the east of 0
longitude at '1999-12-31T23:59:59Z' the solar local time is
'1999-12-31T22:59:59+01:00'
make sense?
-a
···
On Wed, 9 Aug 2006, Tim Pease wrote:
ZONES = class << Time; ZoneOffset.keys.map {|x| x.length == 1 ? x :
nil}.compact.sort; end
ZONES.unshift ZONES.pop
def move_to_zone( utc, longitude )
zone = ZONES[Integer(longitude) / Integer(DEG_PER_HR)]
utc - Time.zone_offset(zone)
end
This does not take into account daylight savings, etc. But give it a
shot and see if it's what you need.
--
to foster inner awareness, introspection, and reasoning is more efficient than
meditation and prayer.
- h.h. the 14th dali lama
i'm starting to think it has to be a float... but a time would be better.
-a
···
On Wed, 9 Aug 2006, Tim Pease wrote:
Clarification question ... do you want the returned value to be a
Float or an actual Time object?
TwP
PS Maybe I should have asked this before posting my little solution there 
--
to foster inner awareness, introspection, and reasoning is more efficient than
meditation and prayer.
- h.h. the 14th dali lama
yes. i'm thinking of something similar - perhaps returning a fraction (of the
current day) or something similar. the reason i was trying to stick with time
objects is to make calculations easier...
it's damn tricky though.
-a
···
On Wed, 9 Aug 2006, Morton Goldberg wrote:
If I understand the problem you describe (likelihood estimate ~ 50%), it's similar to a telemetry data problem I once worked on. Here is how I handled it:
1. express the local solar time value of interest in seconds from local midnight
2. convert the UTC time stamp to seconds from UTC midnight
3. longitude shift the result of 2 to the local time frame
4. compare result of 1 and 3 to determine whether or not to process further
--
to foster inner awareness, introspection, and reasoning is more efficient than
meditation and prayer.
- h.h. the 14th dali lama
too funny. this is a sketch of my code so far:
off_sec =
if longitude > 180.0
((360.0 - longitude) / DEG_PER_HR) * SECS_PER_HR
else
(longitude / DEG_PER_HR) * SECS_PER_HR
end
signedness = off_sec > 0 ? +1 : -1
sign = signedness > 0 ? '+' : '-'
hour_offset, r = off_sec.to_i.abs.divmod SECS_PER_HR
min_offset, r = r.divmod SECS_PER_MIN
hour_offset *= signedness
zone = '%s%-02.2d:%-02.2d' % [sign, hour_offset.to_i, min_offset.to_i.abs]
utc_plus_off = time + off_sec
localtime_expressed_in_utc = Time.parse(utc_plus_off.sub(%r/Z$/, zone)).utc
look familiar 
yeah - this will do it - the time is expressed in utc but at least it's the
actual correct time with respect the ground sampled by the bird at that moment.
thanks for the help - the fact that you came up with that independently makes
me feel better.
-a
···
On Tue, 8 Aug 2006, Tim Pease wrote:
That does make sense. Here's what I came up with based on that ...
class Time
OFFSETS = class << self; ZoneOffset end
ZONES = OFFSETS.keys.select {|z| z.length == 1}.sort
ZONES.unshift ZONES.pop
def translate longitude
zone = ZONES[Integer(longitude) / 15]
t = utc - ::Time.zone_offset(zone)
unless zone == 'Z'
zone = OFFSETS[zone]
str = t.iso8601
str.sub! %r/Z$/, ''
str << (zone > 0 ? '-' : '+')
str << "%02d:00" % zone.abs
t = Time.iso8601 str
end
return t
end
I had to go through and intermediary string in order to get into the
right timezone. Printing out the returned Time object says it is
still in UTC, but that doesn't matter. It's in the correct timezone
for your parsing needs.
If that doesn't work or is not what you want, just shot me a private
e-mail with your work number and I'll cal you
--
to foster inner awareness, introspection, and reasoning is more efficient than
meditation and prayer.
- h.h. the 14th dali lama
I'm not sure I understand what you are trying to do. Are you trying to work out a time-zone by using longitude? Surely not...
Cheers,
Bob
···
On Aug 8, 2006, at 6:42 PM, Ara.T.Howard wrote:
On Tue, 8 Aug 2006, Tim Pease wrote:
That does make sense. Here's what I came up with based on that ...
class Time
OFFSETS = class << self; ZoneOffset end
ZONES = OFFSETS.keys.select {|z| z.length == 1}.sort
ZONES.unshift ZONES.pop
def translate longitude
zone = ZONES[Integer(longitude) / 15]
t = utc - ::Time.zone_offset(zone)
unless zone == 'Z'
zone = OFFSETS[zone]
str = t.iso8601
str.sub! %r/Z$/, ''
str << (zone > 0 ? '-' : '+')
str << "%02d:00" % zone.abs
t = Time.iso8601 str
end
return t
end
I had to go through and intermediary string in order to get into the
right timezone. Printing out the returned Time object says it is
still in UTC, but that doesn't matter. It's in the correct timezone
for your parsing needs.
If that doesn't work or is not what you want, just shot me a private
e-mail with your work number and I'll cal you
too funny. this is a sketch of my code so far:
off_sec =
if longitude > 180.0
((360.0 - longitude) / DEG_PER_HR) * SECS_PER_HR
else
(longitude / DEG_PER_HR) * SECS_PER_HR
end
signedness = off_sec > 0 ? +1 : -1
sign = signedness > 0 ? '+' : '-'
hour_offset, r = off_sec.to_i.abs.divmod SECS_PER_HR
min_offset, r = r.divmod SECS_PER_MIN
hour_offset *= signedness
zone = '%s%-02.2d:%-02.2d' % [sign, hour_offset.to_i, min_offset.to_i.abs]
utc_plus_off = time + off_sec
localtime_expressed_in_utc = Time.parse(utc_plus_off.sub(%r/Z$/, zone)).utc
look familiar 
yeah - this will do it - the time is expressed in utc but at least it's the
actual correct time with respect the ground sampled by the bird at that moment.
thanks for the help - the fact that you came up with that independently makes
me feel better.
-a
--
to foster inner awareness, introspection, and reasoning is more efficient than
meditation and prayer.
- h.h. the 14th dali lama
----
Bob Hutchison -- blogs at <http://www.recursive.ca/hutch/>
Recursive Design Inc. -- <http://www.recursive.ca/>
Raconteur -- <http://www.raconteur.info/>
xampl for Ruby -- <http://rubyforge.org/projects/xampl/>
<snip my own broken code>
for anyone following the thread or searching archvies here's the answer i ended
up with, it's correct afaik:
harp:~ > cat a.rb
require 'date'
require 'time'
···
On Wed, 9 Aug 2006, Ara.T.Howard wrote:
too funny. this is a sketch of my code so far:
#
# returns a datetime object defined at a certain location on earth. in
# otherwords a certian time 'there' not 'here' or 'utc' - a time in an
# arbitrary other timezone.
#
def solar_localtime time, longitude
deg_per_hr = 15
secs_per_hr = 60 * 60
longitude = Float longitude
t =
case time
when Time
time.utc
when DateTime
Time.parse time.to_s
else
Time.parse time.to_s
end
if longitude > 180.0
off_sec = - ((360.0 - longitude) / deg_per_hr) * secs_per_hr
tz = - ((360.0 - longitude) ) / 360.0
else
off_sec = (longitude / deg_per_hr) * secs_per_hr
tz = (longitude ) / 360.0
end
t += off_sec
y, d, h, m, s = %w( year yday hour min sec ).map{|m| t.send m}
DateTime.ordinal y, d, h, m, s, tz
end
#
# demo
#
now = Time.now.utc # you could also do: now = DateTime.now
puts(now.iso8601)
require 'yaml'
[15, 30, 45].each do |longitude|
y longitude => solar_localtime(now, longitude).to_s
y -longitude => solar_localtime(now, -longitude).to_s
end
harp:~ > ruby a.rb
2006-08-09T21:06:33Z
15: 2006-08-09T22:06:32+0100
-15: 2006-08-09T20:06:33-0100
30: 2006-08-09T23:06:33+0200
-30: 2006-08-09T19:06:32-0200
45: 2006-08-10T00:06:33+0300
-45: 2006-08-09T18:06:33-0300
the trick is use DateTime - you can't do it with Time.
regards.
-a
--
to foster inner awareness, introspection, and reasoning is more efficient than
meditation and prayer.
- h.h. the 14th dali lama
yes. not __political__ timezone - actual timezone. each 15 degrees of lon is
exactly one hour so it's easy.
-a
···
On Wed, 9 Aug 2006, Bob Hutchison wrote:
I'm not sure I understand what you are trying to do. Are you trying to work out a time-zone by using longitude? Surely not...
--
to foster inner awareness, introspection, and reasoning is more efficient than
meditation and prayer.
- h.h. the 14th dali lama