# Solar local time

**URL:** <https://www.ruby-forum.com/t/solar-local-time/101941>\
**Category:** Ruby\
**Created:** [August 8, 2006, 8:24pm UTC](https://www.ruby-forum.com/t/solar-local-time/101941 "2006-08-08T20:24:25Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [August 8, 2006, 8:24pm UTC](https://www.ruby-forum.com/t/solar-local-time/101941/1 "2006-08-08T20:24:25Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [August 8, 2006, 8:48pm UTC](https://www.ruby-forum.com/t/solar-local-time/101941/2 "2006-08-08T20:48:27Z")

</div>

On Aug 8, 2006, at 2:23 PM, removed\_email\_address@domain.invalid wrote:

> ```
> SECS_PER_HR = SECS_PER_MIN * 60.0
> end
> 
> ```
> 
> time zone of that **longitude** not mine and not that of greenwich.
> 
> thoughts?

Does TZInfo bring you closer?  
Stolen from the README:

> 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.

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [August 8, 2006, 9:21pm UTC](https://www.ruby-forum.com/t/solar-local-time/101941/3 "2006-08-08T21:21:30Z")

</div>

On Wed, 9 Aug 2006, Logan C. wrote:

> > 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.

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

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [August 8, 2006, 9:24pm UTC](https://www.ruby-forum.com/t/solar-local-time/101941/4 "2006-08-08T21:24:31Z")

</div>

On 8/8/06, removed\_email\_address@domain.invalid [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> ```
> SECS_PER_DAY = SECS_PER_HR * 24
> 
> ```
> 
> locatime\_but\_in\_utc = utc + offset\_seconds
> 
> with
> 
> move\_to\_zone locatime\_but\_in\_utc, longitude
> 
> or some other viable alternative.
> 
> thoughts?

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

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [August 8, 2006, 9:42pm UTC](https://www.ruby-forum.com/t/solar-local-time/101941/5 "2006-08-08T21:42:33Z")

</div>

On 8/8/06, removed\_email\_address@domain.invalid [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> 

snip

> 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 😕

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [August 8, 2006, 11:21pm UTC](https://www.ruby-forum.com/t/solar-local-time/101941/6 "2006-08-08T23:21:42Z")

</div>

On Wed, 9 Aug 2006, Tim P. 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 😕

i’m starting to think it has to be a float… but a time would be  
better.

-a

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [August 8, 2006, 11:21pm UTC](https://www.ruby-forum.com/t/solar-local-time/101941/7 "2006-08-08T23:21:42Z")

</div>

On Wed, 9 Aug 2006, Tim P. wrote:

> shot and see if it’s what you need.  
> 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"
 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

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [August 8, 2006, 11:57pm UTC](https://www.ruby-forum.com/t/solar-local-time/101941/8 "2006-08-08T23:57:43Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [August 9, 2006, 12:27am UTC](https://www.ruby-forum.com/t/solar-local-time/101941/9 "2006-08-09T00:27:45Z")

</div>

On Wed, 9 Aug 2006, Morton G. 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

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
