F
Frank L. Smith
Guest
All,
Somewhere around the end of last year I posted something about getting solar times (sunrise/sunset) from an API. I have limited use for it and honestly I’ve not been paying attention, but at some point after I posted that, it stopped working correctly.
I made it a priority to find and fix that this weekend before I did anything else. Unfortunately it’s not on my end; their API is returning erroneous information. Rather than going down that road, I decided that a better way is by eliminating the web-based API and perform the calculations directly.
This has been done many times by many people over the years so what I’ll present here is based on one them as shown on Code Project here.
That one is done using C# and he used framework 3.5 from VS 2008. Don’t let that concern you though – it will work and you don’t have to change anything!
If you’ll read the article so that you know how it works (it’s pretty short) then download the his assembly and source code, you only need to compile it to a .dll and you can then use it the same as any other once you add a reference to it.
When you open it in your version of Visual Studio you’ll be prompted to convert it. Note that it’s not changing the framework version and you don’t need it to; just let VS do what it does and when it’s done, look in Solution Explorer:
The project named “Astronomy” is the one you want. He has it defaulted to build to the \debug folder and I changed it to the \release folder but other than that, I haven’t changed it one iota and it works great.
If you’d prefer to “just download it” then I have my version of it on my site here:
http://www.fls-online.com/VBNet_Forum/06-10-17/Astronomy.zip
That’s the .dll file zipped up; nothing else.
When you read his article, one part might be confusing which is this (shown in his example code):
const int LongituteTimeZone = 15;
The concept of “LongitudeTimeZone” is never really explained, but it’s this: He needs to know what world time zone to offset from and he’s using 15° longitude lines to do that. On your end, you need to choose the “zone” you’re interested in by selecting one of them.
At first that seems confusing but it’s actually brilliant!
Have a look at the following image and view it at 100%. You’ll see what I mean:
Standard World Time Zone Map
The only part left is a Boolean to indicate whether or not to offset the time in order to compensate for Daylight Saving time.
As for accuracy, is it right? This is what I found by experimenting with a few values for lat/lon and date:
At the end of it all you’ll have three distinctly different sets of times but they’re all *reasonably* close – within 15 minutes or so.
My take on it all is that they’re all just calculations so in my mind, it’s as accurate as any.
*****
My Use Of It
I have taken his assembly and embedded it with some “helper” classes to make things easier. I set this up primarily to make it more compatible with what I had (which I have working again now) and you may also find it to be easier on your end to use mine.
I’ll emphasize that it’s his assembly that’s doing the work, not mine. Mine just uses his a little different way, but under the hood, I’m using his as he intended.
Continuing, with mine I’ve added a twist: I don’t want to have to change “True” to “False” and back again every few month for being in or out of Daylight Savings. What I have will make that process automatic without the need to change and recompile.
Also, I wanted to validate the latitude/longitude coordinates to ensure that they can exist. I’m not doing anything beyond making sure that the latitude is between -90° and +90°, inclusive and that the longitude is between -180° and +180°, inclusive.
The class diagram is shown here and if you’d like to see the source code, I have that here.
The first thing to notice is that my main “class” isn’t a class; it’s a structure. It suits my need but you might want to change yours.
LatLon is a class though and here’s why: I want to ensure that you’ve actually instantiated it and not just using defaults. Testing for a lat/lon of 0,0 won’t work because it’s a legit coordinate. I don’t think anyone lives there:
…but it’s still valid. By making it a class, I can check that it’s not null.
As for the automatic changing of Daylight Savings time, for that I need an instance of the TimeZoneInfo and with that, I can then use the built-in method to tell me whether or not that time zone is currently in Daylight savings or not.
The way that I’m doing that is that you give it the “name” which is either of these two possibilities:
Display Name
Standard Name
Using one of those – and you tell it which it is – it will then take care of the rest.
If you set up a program and you want your users to be able to chose, I have something in there to help with that:
Private Sub _
PopulateCombo(ByVal nameType As TimeZoneData.TimeZoneNameType)
Using combo As New ComboBox
Dim tz As New TimeZoneData
With combo
.AutoCompleteMode = AutoCompleteMode.SuggestAppend
.AutoCompleteSource = AutoCompleteSource.ListItems
Select Case nameType
Case TimeZoneData.TimeZoneNameType.DisplayName
.Items.AddRange(tz.GetAllDisplayNames)
Case TimeZoneData.TimeZoneNameType.StandardName
.Items.AddRange(tz.GetAllStandardNames)
End Select
End With
End Using
End Sub
Following shows a typical use of it:
Dim ll As New LatLon(32.711469, -79.952603)
Dim st As New _
SolarTimes(ll, Today, "Eastern Standard Time", _
TimeZoneData.TimeZoneNameType.StandardName)
The .dll for mine (zipped up) is here and I hope that you might find use from it.
"A problem well stated is a problem half solved.” - Charles F. Kettering
Continue reading...
Somewhere around the end of last year I posted something about getting solar times (sunrise/sunset) from an API. I have limited use for it and honestly I’ve not been paying attention, but at some point after I posted that, it stopped working correctly.
I made it a priority to find and fix that this weekend before I did anything else. Unfortunately it’s not on my end; their API is returning erroneous information. Rather than going down that road, I decided that a better way is by eliminating the web-based API and perform the calculations directly.
This has been done many times by many people over the years so what I’ll present here is based on one them as shown on Code Project here.
That one is done using C# and he used framework 3.5 from VS 2008. Don’t let that concern you though – it will work and you don’t have to change anything!
If you’ll read the article so that you know how it works (it’s pretty short) then download the his assembly and source code, you only need to compile it to a .dll and you can then use it the same as any other once you add a reference to it.
When you open it in your version of Visual Studio you’ll be prompted to convert it. Note that it’s not changing the framework version and you don’t need it to; just let VS do what it does and when it’s done, look in Solution Explorer:
The project named “Astronomy” is the one you want. He has it defaulted to build to the \debug folder and I changed it to the \release folder but other than that, I haven’t changed it one iota and it works great.
If you’d prefer to “just download it” then I have my version of it on my site here:
http://www.fls-online.com/VBNet_Forum/06-10-17/Astronomy.zip
That’s the .dll file zipped up; nothing else.
When you read his article, one part might be confusing which is this (shown in his example code):
const int LongituteTimeZone = 15;
The concept of “LongitudeTimeZone” is never really explained, but it’s this: He needs to know what world time zone to offset from and he’s using 15° longitude lines to do that. On your end, you need to choose the “zone” you’re interested in by selecting one of them.
At first that seems confusing but it’s actually brilliant!
Have a look at the following image and view it at 100%. You’ll see what I mean:
Standard World Time Zone Map
The only part left is a Boolean to indicate whether or not to offset the time in order to compensate for Daylight Saving time.
As for accuracy, is it right? This is what I found by experimenting with a few values for lat/lon and date:
- Use his for a given locale and date, write down the calculated sunrise and sunset times.
- Now use NOAA information with the same data and write down those sunrise and sunset times.
- Lastly, use US Naval Observatory info (they present it in tables) and write those down.
At the end of it all you’ll have three distinctly different sets of times but they’re all *reasonably* close – within 15 minutes or so.
My take on it all is that they’re all just calculations so in my mind, it’s as accurate as any.
*****
My Use Of It
I have taken his assembly and embedded it with some “helper” classes to make things easier. I set this up primarily to make it more compatible with what I had (which I have working again now) and you may also find it to be easier on your end to use mine.
I’ll emphasize that it’s his assembly that’s doing the work, not mine. Mine just uses his a little different way, but under the hood, I’m using his as he intended.
Continuing, with mine I’ve added a twist: I don’t want to have to change “True” to “False” and back again every few month for being in or out of Daylight Savings. What I have will make that process automatic without the need to change and recompile.
Also, I wanted to validate the latitude/longitude coordinates to ensure that they can exist. I’m not doing anything beyond making sure that the latitude is between -90° and +90°, inclusive and that the longitude is between -180° and +180°, inclusive.
The class diagram is shown here and if you’d like to see the source code, I have that here.
The first thing to notice is that my main “class” isn’t a class; it’s a structure. It suits my need but you might want to change yours.
LatLon is a class though and here’s why: I want to ensure that you’ve actually instantiated it and not just using defaults. Testing for a lat/lon of 0,0 won’t work because it’s a legit coordinate. I don’t think anyone lives there:
…but it’s still valid. By making it a class, I can check that it’s not null.
As for the automatic changing of Daylight Savings time, for that I need an instance of the TimeZoneInfo and with that, I can then use the built-in method to tell me whether or not that time zone is currently in Daylight savings or not.
The way that I’m doing that is that you give it the “name” which is either of these two possibilities:
Display Name
Standard Name
Using one of those – and you tell it which it is – it will then take care of the rest.
If you set up a program and you want your users to be able to chose, I have something in there to help with that:
Private Sub _
PopulateCombo(ByVal nameType As TimeZoneData.TimeZoneNameType)
Using combo As New ComboBox
Dim tz As New TimeZoneData
With combo
.AutoCompleteMode = AutoCompleteMode.SuggestAppend
.AutoCompleteSource = AutoCompleteSource.ListItems
Select Case nameType
Case TimeZoneData.TimeZoneNameType.DisplayName
.Items.AddRange(tz.GetAllDisplayNames)
Case TimeZoneData.TimeZoneNameType.StandardName
.Items.AddRange(tz.GetAllStandardNames)
End Select
End With
End Using
End Sub
Following shows a typical use of it:
Dim ll As New LatLon(32.711469, -79.952603)
Dim st As New _
SolarTimes(ll, Today, "Eastern Standard Time", _
TimeZoneData.TimeZoneNameType.StandardName)
The .dll for mine (zipped up) is here and I hope that you might find use from it.
"A problem well stated is a problem half solved.” - Charles F. Kettering
Continue reading...