PyEphem: Best way to set observer time to Midnight local time from current UTC - pyephem

I struggling to find an elegant way to set the ephem observer time to midnight local time. That is convert from midnight local time to ephem's UTC.
ephem uses next_rising to find the next sunrise time. Problem is if the local time is already past sunrise if gives you tomorrows sunrise.
I want to set my observer time to midnight local time so the next_rising , next_setting and next_transit are for the current day.
Going round in circles with python datetime stuff.
import ephem
home = ephem.Observer()
home.date = ephem.now()
home.lat = str(-37.8136)
home.lon = str(144.9631)
sunrise = home.next_rising( ephem.Sun() )
print home.date
# 2018/3/13 05:54:04
print ephem.localtime( home.date )
# 2018-03-13 16:54:03.000001 - current date is 13th March
print sunrise
# 2018/3/13 20:16:38 - sunrise in UTC
print ephem.localtime( sunrise )
# 2018-03-14 07:16:37.000002 - next date sunrise 14th March

Using this post How do I get the UTC time of "midnight" for a given timezone?
The following works
#!/usr/bin/env python
from datetime import datetime, time
import pytz # pip instal pytz
import ephem
tz = pytz.timezone("Australia/Melbourne") # choose timezone
today = datetime.now(tz).date()
# assert that there is no dst transition at midnight (`is_dst=None`)
midnight = tz.localize(datetime.combine(today, time(0, 0)), is_dst=None)
# convert to UTC
fmt = '%Y-%m-%d %H:%M:%S'
print midnight.astimezone(pytz.utc).strftime(fmt)
home = ephem.Observer()
home.date = ephem.now()
home.date = ephem.Date( midnight.astimezone(pytz.utc).strftime(fmt) )
print home.date

Related

Why does DateTime's strftime give the wrong year when I subtract days from dates near the end of a year?

I have to open some logs that have a date in the filename. So I am trying to open all the files through a certain date.
I'm using DateTime. I do:
do
{
$datechoice = $today->strftime('%G%m%d'); #YearMonthDay
$date_for_graph = $today->strftime('%d/%m/%G');
# unshift #Log_Period_Time, "$date_for_graph";
print $datechoice." - ".$date_for_graph."<br>";
$today->subtract(days => 1);
} while($datechoice > 20141107);
But the output shows the wrong year for dates near the end of a year:
20160109 - 09/01/2016
20160108 - 08/01/2016
20160107 - 07/01/2016
20160106 - 06/01/2016
20160105 - 05/01/2016
20160104 - 04/01/2016
20150103 - 03/01/2015 <-- Should be 2016
20150102 - 02/01/2015
20150101 - 01/01/2015
20151231 - 31/12/2015
20151230 - 30/12/2015
20151229 - 29/12/2015
...
20150103 - 03/01/2015
20150102 - 02/01/2015
20150101 - 01/01/2015
20151231 - 31/12/2015
20151230 - 30/12/2015
20151229 - 29/12/2015
20141228 - 28/12/2014 <-- Should be 2015
20141227 - 27/12/2014
20141226 - 26/12/2014
Why is this happening?
Use %Y, not %G, unless you specifically mean to display the date according to the ISO 8601 week number calendar.
(In the ISO calendar, every year is a whole number of weeks running Monday-Sunday. So whenever January 1st isn't a Monday there will be up to three days on one side of it that fall in the "wrong" year by ISO reckoning. For instance, ISO year 2021 started on Monday, January 4th; January 1st through 3rd fell in the last week of 2020. Going the other way, ISO year 2026 will start on Monday, December 29th, 2025, so the last 3 days of that December are already the first week of the next ISO year.)

Gnuplot prints a strange year, 30 years later

I have the next problem with gnuplot, when I print the time gnuplot
prints de time+30years.
This is a part of my data:
1411336800,1390,0,0,0,10,1411,0,10,0,0,0,0,0,1411
1411340400,1506,0,0,0,10,969,0,10,0,0,0,0,0,969
1411344000,1115,0,0,0,10,1108,0,10,0,0,0,0,0,1108
1411347600,719,0,0,0,10,712,0,10,0,0,0,0,0,712
A part of the script is:
set timefmt "%s"
stats "<tail -1 uur.txt " using 1:2 nooutput
tijd = strftime("%d %B %Y %H:%M", STATS_max_x)
print tijd
And then gnuplot prints: 21 September 2044 01:00. 44 ?
Has some one a clue?
I tried several formats but nothing helped.
Until version 4.6, internally gnuplot uses the 1. January 2000 as reference for its date and time functions (in version 5.0 the standard Unix timestamp is used).
You shouldn't have any problems with set timefmt "%s" if you plot the data. But when using strftime it makes a difference. Since you're using tail anyway, you can simply use
tijd = system('date -d #$(tail -1 uur.txt | cut -d, -f1) +"%d %B %Y %H:%M"')
print tijd

UNIX: Convert Unix Date in Specific format

I have some date other than current date in unix and I want to convert into a specific format
Original Format
D="Mon Dec 30 06:35:02 EST 2013"
New Format
E=20131230063502
E=`date +%Y%m%d%H%M%S`
this is the way to format the output of the date command and save it in the variable E
Using python:
def data(dstr):
m = {'Jan': '01', 'Feb':'02', 'Mar':'03', 'Apr':'04', 'May':'05', 'Jun':'06', 'Jul':'07', 'Aug':'08', 'Sep':'09', 'Oct':'10', 'Nov':'11', 'Dec':'12'}
val = dstr.split(' ')
month = m[val[1]]
time = val[3].split(':')
return '{}{}{}{}{}{}'.format(val[-1],month,val[2],time[0],time[1],time[2])
if __name__ == '__main__':
print data("Mon Dec 30 06:35:02 EST 2013")
In: Mon Dec 30 06:35:02 EST 2013
Out: 20131230063502

Powershell: get-date & [datetime]::FromFileTime returns different values

Why does get-date & [datetime]::FromFileTime returns different values when converting FileTime? An example:
Get-Date 129442497539436142
returns Thursday, March 10, 0411 4:55:53 PM, but
[datetime]::FromFileTime("129442497539436142")
returns Thursday, March 10, 2011 11:55:53 AM
They produce the same result for me, presumably because I'm in GMT.
(FromFileTime parses the time as UTC, Get-Date appears to be using your local time.)
FileTimes are so-called Ticks. 10 million pass every second. Filetime are 0 at midnight, January 1st 1601 (UTC).
Get-date also have ticks, but the base of ticks used by Get-Date is NOT 1601.
It is January 1st year 1.
You can basically identify the 2 different types of ticks by the first digit.
Filetime ticks starts with digit 1 in the rough range of -100 to + 200 years from now.
The ticks using base on January 1st year 0 starts with 6 in roughly the same time range...
In PowerShell you can get verify Jan. 1st year 1 is tick 0 by typing:
[datetime]'0001-01-01' | Select-Object -property Ticks
Get-Date get ticks from 01/01/0001 00:00
[datetime]::FromFileTimeUTC($a) get ticks from 01/01/1601 00:00
You wrote:
returns Thursday, March 10, 0411 4:55:53 PM, but
returns Thursday, March 10, 2011 11:55:53 AM
The difference is 1600 years
This is an example:
$a = ([datetime]::Now).Ticks - ([DateTime]("01/01/0001 00:00")).Ticks
Get-Date $a # get ticks from 01/01/0001 00:00
$a = ([datetime]::Now).Ticks - ([datetime]("01/01/1601 00:00")).Ticks
[datetime]::FromFileTimeUTC($a) # get ticks from 01/01/1601 00:00
It is based on your local "long date" format.
enter image description here
Either you have to change your system "Long Date"
(OR) Use below command
(get-date).tostring("dd/MM/yyyy")
enter image description here
https://technet.microsoft.com/en-us/library/ee692801.aspx
Regards,
Manikandan Boopathy

How do I elegantly print the date in RFC822 format in Perl?

How can I elegantly print the date in RFC822 format in Perl?
use POSIX qw(strftime);
print strftime("%a, %d %b %Y %H:%M:%S %z", localtime(time())) . "\n";
The DateTime suite gives you a number of different ways, e.g.:
use DateTime;
print DateTime->now()->strftime("%a, %d %b %Y %H:%M:%S %z");
use DateTime::Format::Mail;
print DateTime::Format::Mail->format_datetime( DateTime->now() );
print DateTime->now( formatter => DateTime::Format::Mail->new() );
Update: to give time for some particular timezone, add a time_zone argument
to now():
DateTime->now( time_zone => $ENV{'TZ'}, ... )
It can be done with strftime, but its %a (day) and %b (month) are expressed in the language of the current locale.
From man strftime:
%a The abbreviated weekday name according to the current locale.
%b The abbreviated month name according to the current locale.
The Date field in mail must use only these names (from rfc2822 DATE AND TIME SPECIFICATION):
day = "Mon" / "Tue" / "Wed" / "Thu" / "Fri" / "Sat" / "Sun"
month = "Jan" / "Feb" / "Mar" / "Apr" / "May" / "Jun" /
"Jul" / "Aug" / "Sep" / "Oct" / "Nov" / "Dec"
Therefore portable code should switch to the C locale:
use POSIX qw(strftime locale_h);
my $old_locale = setlocale(LC_TIME, "C");
my $date_rfc822 = strftime("%a, %d %b %Y %H:%M:%S %z", localtime(time()));
setlocale(LC_TIME, $old_locale);
print "$date_rfc822\n";
Just using POSIX::strftime() has issues that have already been pointed out in other answers and comments on them:
It will not work with MS-DOS aka Windows which produces strings like "W. Europe Standard Time" instead of "+0200" as required by RFC822 for the %z conversion specification.
It will print the abbreviated month and day names in the current locale instead of English, again required by RFC822.
Switching the locale to "POSIX" resp. "C" fixes the latter problem but is potentially expensive, even more for well-behaving code that later switches back to the previous locale.
But it's also not completely thread-safe. While temporarily switching locale will work without issues inside Perl interpreter threads, there are races when the Perl interpreter itself runs inside a kernel thread. This can be the case, when the Perl interpreter is embedded into a server (for example mod_perl running in a threaded Apache MPM).
The following version doesn't suffer from any such limitations because it doesn't use any locale dependent functions:
sub rfc822_local {
my ($epoch) = #_;
my #time = localtime $epoch;
use integer;
my $tz_offset = (Time::Local::timegm(#time) - $now) / 60;
my $tz = sprintf('%s%02u%02u',
$tz_offset < 0 ? '-' : '+',
$tz_offset / 60, $tz_offset % 60);
my #month_names = qw(Jan Feb Mar Apr May Jun
Jul Aug Sep Oct Nov Dec);
my #day_names = qw(Sun Mon Tue Wed Thu Fri Sat Sun);
return sprintf('%s, %02u %s %04u %02u:%02u:%02u %s',
$day_names[$time[6]], $time[3], $month_names[$time[4]],
$time[5] + 1900, $time[2], $time[1], $time[0], $tz);
}
But it should be noted that converting from seconds since the epoch to a broken down time and vice versa are quite complex and expensive operations, even more when not dealing with GMT/UTC but local time. The latter requires the inspection of zoneinfo data that contains the current and historical DST and time zone settings for the current time zone. It's also error-prone because these parameters are subject to political decisions that may be reverted in the future. Because of that, code relying on the zoneinfo data is brittle and may break, when the system is not regulary updated.
However, the purpose of RFC822 compliant date and time specifications is not to inform other servers about the timezone settings of "your" server but to give its notion of the current date and time in a timezone indepent manner. You can save a lot of CPU cycles (they can be measured in CO2 emission) on both the sending and receiving end by simply using UTC instead of localtime:
sub rfc822_gm {
my ($epoch) = #_;
my #time = gmtime $epoch;
my #month_names = qw(Jan Feb Mar Apr May Jun
Jul Aug Sep Oct Nov Dec);
my #day_names = qw(Sun Mon Tue Wed Thu Fri Sat Sun);
return sprintf('%s, %02u %s %04u %02u:%02u:%02u +0000',
$day_names[$time[6]], $time[3], $month_names[$time[4]],
$time[5] + 1900, $time[2], $time[1], $time[0]);
}
By hard-coding the timezone to +0000 you avoid all of the above mentioned problems, while still being perfectly standards compliant, leave alone faster. Go with that solution, when performance could be an issue for you. Go with the first solution, when your users complain about the software reporting the "wrong" timezone.