Gnuplot prints a strange year, 30 years later - date

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

Related

parse javascript date to elixir format

I have some saved dates in JavaScript using new Date() that looks like:
"Sun Feb 24 2019 14:44:20 GMT+0200 (Eastern European Standard Time)"
I'm trying to parse these to Elixir DateTime; I didn't find anything in "timex" that can help and I already know that I can use DateTime.from_iso8601 but for dates saved using new Date().toISOString() but what i need is to parse the above string.
Thanks in advance
You can use elixir binary pattern matching to extract the date parts and parse using Timex's RFC1123 format. The RFC1123 is the format e.g Tue, 05 Mar 2013 23:25:19 +0200. Run h Timex.Format.DateTime.Formatters.Default in iex to see other formats.
iex> date_string = "Sun Feb 24 2019 14:44:20 GMT+0200 (Eastern European Standard Time)"
iex> <<day_name::binary-3,_,month_name::binary-3,_,day::binary-2,_,year::binary-4,_,time::binary-8,_::binary-4,offset::binary-5,_,rest::binary>> = date_string
iex> Timex.parse("#{day_name}, #{day} #{month_name} #{year} #{time} #{offset}", "{RFC1123}")
iex> {:ok, #DateTime<2019-02-24 14:44:20+02:00 +02 Etc/GMT-2>}
Pattern matching:
The binary-size are in byte sizes. 1 byte == 1 character. For instance to get
3-character day_name the size is 3. Underscores (_) is used to pattern match the spaces in the date format
Updated answer to use binary-size rather than bitstring-size for simplicity
I didn't find anything in "timex" that can help
The Timex Parsing docs say that you can use strftime sequences, e.g %H:%M:%S, for parsing. Here's a list of strftime characters and what they match.
Here's a format string that I think should work on javascript Dates:
def parse_js_date() do
Timex.parse!("Sun Feb 24 2019 14:44:20 GMT+0200 (Eastern European Standard Time)",
"%a %b %d %Y %H:%M:%S GMT%z (%Z)",
:strftime)
end
Unfortunately, %Z doesn't want to match the time zone name, which causes Timex.parse!() to spit out an error. It looks like %Z in Elixir only matches one word, e.g. a timezone abbreviation EET. Therefore, my simple, clean solution is spoiled.
What you can do is chop off the time zone name before parsing the date string:
def parse_js_date_string() do
[date_str|_tz_name] = String.split(
"Sun Feb 24 2019 14:44:20 GMT+0200 (Eastern European Standard Time)",
" (",
parts: 2
)
Timex.parse!(date_str,
"%a %b %d %Y %H:%M:%S GMT%z",
:strftime)
end
In iex:
~/elixir_programs/my$ iex -S mix
Erlang/OTP 20 [erts-9.3] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false]
Compiling 1 file (.ex)
Interactive Elixir (1.6.6) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> My.parse_js_date_string()
#DateTime<2019-02-24 14:44:20+02:00 +02 Etc/GMT-2>
iex(2)>

text processing to select date range

I have below input and I want to select lines with dates from now to 2 weeks or 3 weeks and so on.
0029L5 08/19/2017 00:57:33
0182L5 08/19/2017 05:53:57
0183L5 02/17/2018 00:00:16
0091L5 10/19/2022 00:00:04
0045L5 07/27/2017 09:03:56
0059L5 08/14/2017 00:51:50
0100L5 08/20/2017 01:25:39
0111L5 08/21/2017 00:46:15
0128L5 08/21/2017 12:38:51
D00054 07/21/2017 09:01:19
So the desired output if let say I want for 2 weeks from now
0045L5 07/27/2017 09:03:56
D00054 07/21/2017 09:01:19
But if i want for let say 4 weeks then the output should be
0045L5 07/27/2017 09:03:56
0059L5 08/14/2017 00:51:50
D00054 07/21/2017 09:01:19
One way:
awk '{split($2,a,"/");split($3,b,":"); x=mktime(a[3]" "a[1]" "a[2]" "b[1]" "b[2]" "b[3]);y=systime();}x>y && x<(y+(n*7*24*60*60))' n=2 file
where n indicates the number of weeks
split($2,a,"/") => Split the 2nd column on the basis of / and store in array a
split($3,b,":") => Split the 3rd column on the basis of : and store in array b
mktime => gives the time in seconds
x contains the time in file in seconds
y contains the current time in seconds
Here's one solution using bash where file is the name of your file:
while read r; do dd=$(($(date -d "${r:6}" +%s) - $(date +%s))); echo $(($dd/(3600*24))); done < file
This will compute the date difference in seconds between the date in ${r:6} (substring of the current row) and today's date $(date +%s) and convert it to days.
To output only lines where the date difference is less than 2 weeks (1209600 seconds)
while read r; do dd=$(($(date -d "${r:6}" +%s) - $(date +%s))); if [ "$dd" -lt 1209600 ]; then echo $r; fi; done < file
This works fine, Please let me know in case anybody has any other simpler solution for AIX.
awk '{split($2,a,"/");split($3,b,":"); print $1,b[3],b[2],b[1],a[2],a[1],a[3]}' /tmp/TLD_1 | head -10 | while read media sec min hour day mon year; do month=$((10#$mon-1)); expiry=$(perl -e 'use Time::Local; print timegm(#ARGV[0,1,2,3], $ARGV[4], $ARGV[5]), "\n";' $sec $min $hour $day $month $year); current=$(date +%s); twoweeks=$(($current + (2*7*24*60*60))); if [ "$expiry" -gt "$current" -a "$expiry" -lt "$twoweeks" ]; then echo "$media $mon/$day/$year $hour:$min:$sec"; fi; done

Script to add day not date to filename

I need to create a script batch, PowerShell or VB to add the day of the week to the filename.
For example, there are 4 files and all need to have MON apended to the front on Mondays, TUE on Tuesdays, WED on Wednesdays, etc.
Can anyone assist with this please?
$dow = (Get-Date -f ddd).ToUpper()
$fileName = "${dow}_your_file_name.txt "
THU_your_file_name.txt
Use the VBScript Docs or Google for details on the Weekday() and WeekdayName() functions used in:
Today = Date()
DayNum = Weekday(Today)
DayName = WeekdayName(DayNum, True)
WScript.Echo UCase(DayName) & "_" & "somefile.txt"
THU_somefile.txt
PS:
Start here: Functions (VBScript)
Well, there's an answer for powershell and one for VBScript. Here's one for Windows cmd batch.
#echo off
setlocal
for /f "tokens=5" %%I in ('find "" "%date:~0,3%" 2^>^&1') do set day=%%I
ren "oldfile.txt" "%day%_oldfile.txt"
Explanation
:: DIRECTIVE RESULT
:: --------------------------------------------------------
:: %date% Thu 02/07/2013
:: %date:~0,3% Thu
:: find "" "Thu" error stating "File not found - THU"
:: --------------------------------------------------------
Then all that remains is to redirect the error from stderr to stdout and scrape the fifth token.
(source of idea to use find to convert to upper case)
if you choose VBScript, be careful with WeekDayName function as it related to regional language settings. For example, Friday is Петък (in Bulgarian), so in my system WeekDayName with abbreviate set to True will return Пт, not Fri.
WScript.Echo WeekDayAbbrENG()
Function WeekDayAbbrENG()
Dim WDs
WDs = Split("SUN MON TUE WED THU FRI SAT")
WeekDayAbbrENG = WDs(Weekday(Now) - 1)
End Function
[EDIT] Actually, the same problem appear with Get-Date in PowerShell.

pyephem: can't calculate sunrise/set for polar regions

i'm trying to calculate sunrises and sunsets using pyephem, but the algorithm never seems to converge for polar regions?
observe the sample code below. it iterates through an entire year in 10-minute increments asking for the next sunrise and sunset. pyephem always returns with an AlwaysUpError or NeverUpError, but surely the sun must rise and set at least once during the year?
import ephem
from datetime import datetime, timedelta
obs = ephem.Observer()
obs.lat = '89:30'
obs.long = '0'
start = datetime(2011, 1, 1)
end = datetime(2012, 1, 1)
step = timedelta(minutes=10)
sun = ephem.Sun()
timestamp = start
while timestamp < end:
obs.date = timestamp
try:
print obs.next_rising(sun)
except (ephem.AlwaysUpError, ephem.NeverUpError):
pass
try:
print obs.next_setting(sun)
except (ephem.AlwaysUpError, ephem.NeverUpError):
pass
try:
print obs.previous_rising(sun)
except (ephem.AlwaysUpError, ephem.NeverUpError):
pass
try:
print obs.previous_setting(sun)
except (ephem.AlwaysUpError, ephem.NeverUpError):
pass
timestamp += step
either i'm using the api incorrectly, there's a bug in pyephem, or i'm misunderstanding something fundamental. any help?
I suspect some sort of improper caching. Consider:
import ephem
atlanta = ephem.Observer()
atlanta.pressure = 0
atlanta.horizon = '-0:34'
atlanta.lat, atlanta.lon = '89:30', '0'
atlanta.date = '2011/03/18 12:00'
print atlanta.previous_rising(ephem.Sun())
print atlanta.next_setting(ephem.Sun())
atlanta.date = '2011/03/19 12:00'
print atlanta.previous_rising(ephem.Sun())
print atlanta.next_setting(ephem.Sun())
atlanta.date = '2011/03/20 12:00'
print atlanta.previous_rising(ephem.Sun())
# print atlanta.next_setting(ephem.Sun())
atlanta.date = '2011/09/24 12:00'
# print atlanta.previous_rising(ephem.Sun())
print atlanta.next_setting(ephem.Sun())
atlanta.date = '2011/09/25 12:00'
print atlanta.previous_rising(ephem.Sun())
print atlanta.next_setting(ephem.Sun())
atlanta.date = '2011/09/26 12:00'
print atlanta.previous_rising(ephem.Sun())
print atlanta.next_setting(ephem.Sun())
which yields:
2011/3/18 07:49:34
2011/3/18 17:44:50
2011/3/19 05:04:49
2011/3/19 21:49:23
2011/3/20 01:26:02
2011/9/24 19:59:09
2011/9/25 04:57:21
2011/9/25 17:14:10
2011/9/26 08:37:25
2011/9/26 14:03:20
which matches to the minute with USNO results:
https://raw.github.com/barrycarter/bcapps/master/db/srss-895.txt
See also my related whiny complain in linked question.
I just ran your program and got this output (piped to "sort | uniq -c"):
260 2011/3/17 11:32:31
469 2011/3/17 13:42:56
184 2011/3/18 07:25:56
350 2011/3/18 18:13:15
191 2011/3/19 04:41:42
346 2011/9/24 20:25:13
337 2011/9/25 04:27:45
214 2011/9/25 17:36:10
166 2011/9/26 08:00:59
254 2011/9/26 14:37:06
Are you sure you have the indentations right? Here's my raw code:
https://raw.github.com/barrycarter/bcapps/master/playground4.py
(the output doesn't match my other answer above, but we're using different horizons (-34 minutes vs -50 minutes).
i've found using the start parameter to obs.next_rising(), etc., yield better results. however it still sometimes seems to miss certain crossings; the rises it finds don't always pair off with a corresponding set.

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.