Unix time in millisecond to d-m-Y - php-5.2

I'm pulling a unix time in milliseconds from an xml document but can't convert it to a readable date (d-m-Y) in php 5.2.17.
I've used http://www.epochconverter.com/ which converts it correctly
from 1328723926776 to 2/9/2012 13:37:49
I've tried the following:
$timestamp = $xml['LastBackupDate'];
echo '<br />Method 1: '.date("d-m-Y", $timestamp);
echo '<br />Method 2: '.date("d-m-Y", strtotime($timestamp));
echo '<br />Method 3: '.date("d-m-Y", strtotime($timestamp*1000));
echo '<br />Method 4: '.date("d-m-Y", strtotime($timestamp/1000));
echo '<br />Method 5: '.date("d-m-Y", $timestamp/1000);
echo '<br />Method 6: '.date("d-m-Y", (int)$timestamp);
echo '<br />Method 7: '.date("d-m-Y", intval($timestamp));
echo '<br />Method 8: '.date("d-m-Y", intval($timestamp)/1000);
echo '<br />Method 9: '.date("d-m-Y", intval($timestamp/1000));
which brings back:
Method 1:
Method 2: 01-01-1970
Method 3: 01-01-1970
Method 4: 01-01-1970
Method 5: 25-01-1970
Method 6: 19-01-2038
Method 7: 19-01-2038
Method 8: 25-01-1970
Method 9: 25-01-1970
Any ideas how to convert this?
Thanks!
Edit, Best result from using:
echo date("d-m-Y", substr($xml['LastBackupDate'],0,-3));

Have you tried dividing by 1000, instead of multiplying? Epoch time is usually in seconds ...
OK, so now I actually need to learn PHP ...
date takes a format and a time.
strtotime takes a human-readable date/time string and returns a time. Your value is epoch time in milliseconds, not a human-readable string, so isn't a valid argument to strtotime.
Try Method 4 without the strtotime, it shouldn't be needed.
Right, that didn't work, because $timestamp is a string (I'd assumed it was already an integer).
You say that dropping the last 3 characters of the string gets you most of the way, that is the same as converting to an integer and then dividing by 1,000. Your methods 6 & 7 convert to int but don't divide - you need both!
According to this, date requires an integer timestamp in seconds. The value you have is a string, so you should convert it to an integer. It is also in milliseconds, so you have to divide by 1,000 to get the right units.
Note that epoch time is counted as seconds since the first of January, 1970. So, any time you see 01-01-1970, the second argument evaluated to zero.
date("d-m-Y", $timestamp); <-- string, not int: treated as zero
date("d-m-Y", strtotime($timestamp)); <-- not a formatted time, gives zero
date("d-m-Y", strtotime($timestamp*1000)); <-- ditto
date("d-m-Y", strtotime($timestamp/1000)); <-- ditto
date("d-m-Y", $timestamp/1000); <-- clearly nonzero, but no idea what!
date("d-m-Y", (int)$timestamp); <-- correct type but in milliseconds
date("d-m-Y", intval($timestamp)); <-- correct type but in milliseconds
If you pass an integer containing a number of seconds rather than milliseconds, it should be correct.
Like so:
date("d-m-Y", intval($timestamp)/1000);

Related

How do I print multiple variables on the same line in the DolphinDB GUI?

I want to print the following variables on the same line:
print('pre_date', pre_date, 'date', date)
Execute the script in GUI and the output is:
pre_date
2021.01.06T00:00:00.000000000
date
2021.01.06T00:00:00.000000000
The result is displayed on 4 separate lines. How to output them on the same line?
You can use the plus sign (“+”) to concatenate strings together and print it out:
print('pre_date:' + string(pre_date) + ',date:' + string(date))

How can I extract some data out of the middle of a noisy file using Perl 6?

I would like to do this using idiomatic Perl 6.
I found a wonderful contiguous chunk of data buried in a noisy output file.
I would like to simply print out the header line starting with Cluster Unique and all of the lines following it, up to, but not including, the first occurrence of an empty line. Here's what the file looks like:
</path/to/projects/projectname/ParameterSweep/1000.1.7.dir> was used as the working directory.
....
Cluster Unique Sequences Reads RPM
1 31 3539 3539
2 25 2797 2797
3 17 1679 1679
4 21 1636 1636
5 14 1568 1568
6 13 1548 1548
7 7 1439 1439
Input file: "../../filename.count.fa"
...
Here's what I want parsed out:
Cluster Unique Sequences Reads RPM
1 31 3539 3539
2 25 2797 2797
3 17 1679 1679
4 21 1636 1636
5 14 1568 1568
6 13 1548 1548
7 7 1439 1439
One-liner version
.say if /Cluster \s+ Unique/ ff^ /^\s*$/ for lines;
In English
Print every line from the input file starting with the once containing the phrase Cluster Unique and ending just before the next empty line.
Same code with comments
.say # print the default variable $_
if # do the previous action (.say) "if" the following term is true
/Cluster \s+ Unique/ # Match $_ if it contains "Cluster Unique"
ff^ # Flip-flop operator: true until preceding term becomes true
# false once the term after it becomes true
/^\s*$/ # Match $_ if it contains an empty line
for # Create a loop placing each element of the following list into $_
lines # Create a list of all of the lines in the file
; # End of statement
Expanded version
for lines() {
.say if (
$_ ~~ /Cluster \s+ Unique/ ff^ $_ ~~ /^\s*$/
)
}
lines() is like <> in perl5. Each line from each file listed on the command line is read in one at a time. Since this is in a for loop, each line is placed in the default variable $_.
say is like print except that it also appends a newline. When written with a starting ., it acts directly on the default variable $_.
$_ is the default variable, which in this case contains one line from the file.
~~ is the match operator that is comparing $_ with a regular expression.
// Create a regular expression between the two forward slashes
\s+ matches one or more spaces
ff is the flip-flop operator. It is false as long as the expression to its left is false. It becomes true when the expression to its left is evaluated as true. It becomes false when the expression to its right becomes true and is never evaluated as true again. In this case, if we used ^ff^ instead of ff^, then the header would not be included in the output.
When ^ comes before (or after) ff, it modifies ff so that it is also false the iteration that the expression to its left (or right) becomes true.
/^\*$/ matches an empty line
^ matches the beginning of a string
\s* matches zero or more spaces
$ matches the end of a string
By the way, the flip-flop operator in Perl 5 is .. when it is in a scalar context (it's the range operator in list context). But its features are not quite as rich as in Perl 6, of course.
I would like to do this using idiomatic Perl 6.
In Perl, the idiomatic way to locate a chunk in a file is to read the file in paragraph mode, then stop reading the file when you find the chunk you are interested in. If you are reading a 10GB file, and the chunk is found at the top of the file, it's inefficient to continue reading the rest of the file--much less perform an if test on every line in the file.
In Perl 6, you can read a paragraph at a time like this:
my $fname = 'data.txt';
my $infile = open(
$fname,
nl => "\n\n", #Set what perl considers the end of a line.
); #Removed die() per Brad Gilbert's comment.
for $infile.lines() -> $para {
if $para ~~ /^ 'Cluster Unique'/ {
say $para.chomp;
last; #Quit reading the file.
}
}
$infile.close;
# ^ Match start of string.
# 'Cluster Unique' By default, whitespace is insignificant in a perl6 regex. Quotes are one way to make whitespace significant.
However, in perl6 rakudo/moarVM the open() function does not read the nl argument correctly, so you currently can't set paragraph mode.
Also, there are certain idioms that are considered by some to be bad practice, like:
Postfix if statements, e.g. say 'hello' if $y == 0.
Relying on the implicit $_ variable in your code, e.g. .say
So, depending on what side of the fence you live on, that would be considered a bad practice in Perl.

Dot rules in nested conditional statements - COBOL

I'm wondering if anybody can explain to me the dot ruling in nested IF statements in COBOL. Example:
*The first if statement*
IF SUCCESSFUL-STATUS
PERFORM 8300-REPL-LNNTBI00
THRU 8300-REPL-LNNTBI00-EXIT
*The second if statement*
IF SUCCESSFUL-STATUS
DISPLAY 'RECORD ALREADY UPDATED :' WS-INF-REC
ELSE
DISPLAY 'UPDATE ERROR : ' WS-INF-REC ' / '
WS-RETURN-STATUS
READ INFILE INTO WS-INF-REC.
Which if statement does the dot placed after "WS-INF-REC" belong to? The first IF or the second IF-ELSE? I know that in most programming, it should be for the last if statement but just to make sure, is it the same for COBOL?
AFAIR a period always closes ALL preceding statements - regardless wether they are IF, PERFORM or whatever - so in your case the first IF-statement is closed as well. And since periods are so small and easily overlooked I use the following rule:
Avoid using periods, they are evil!
Only put a period where it is strictly required by the syntax rules and nowhere else. Use explicit scope-terminators like END-IF or END-PERFORM. They make your code more readable and clearly structured while periods tend to generate confusion because of multiple closures and their habit of hiding in plain view.
The period character "." ends all if statements. Remember that spacing is ignored by the compiler so therefore the READ statement is part of the ELSE of the second IF statement.
Us humans want to see the indentation used logically. And, if it were me, I would make the end-if's be explicit. I tend to have one period per paragraph:
* The first if statement *
IF SUCCESSFUL-STATUS
PERFORM 8300-REPL-LNNTBI00
THRU 8300-REPL-LNNTBI00-EXIT
* The second if statement*
IF SUCCESSFUL-STATUS
DISPLAY 'RECORD ALREADY UPDATED :' WS-INF-REC
ELSE
DISPLAY 'UPDATE ERROR : ' WS-INF-REC ' / '
WS-RETURN-STATUS
READ INFILE INTO WS-INF-REC
END-IF
END-IF
.
This is really bad, very archaic Cobol, but how it behaves is like this:
*The first if statement*
IF SUCCESSFUL-STATUS
PERFORM 8300-REPL-LNNTBI00
THRU 8300-REPL-LNNTBI00-EXIT
*The second if statement*
IF SUCCESSFUL-STATUS
DISPLAY 'RECORD ALREADY UPDATED :' WS-INF-REC
ELSE
DISPLAY 'UPDATE ERROR : ' WS-INF-REC ' / ' WS-RETURN-STATUS
READ INFILE INTO WS-INF-REC
END-IF ## from period
END-IF ## from period

AppleScript parsing html from site

What I'm trying to do is to get the names of all TV shows on this Wikipedia page.
Ok, so I did this first:
property showsWebList : {}
tell application "Safari"
set loadDelay to 2 -- in seconds; test for your system
make new document at end of every document
set URL of document 1 to "http://en.wikipedia.org/wiki/List_of_television_programs_by_name"
delay loadDelay
set nrOfUls to do JavaScript "document.getElementById('mw-content-text').querySelectorAll('ul').length;" in document 1
set nrOfUls to nrOfUls - 1 as number
log nrOfUls
repeat with ws from 1 to nrOfUls
delay loadDelay
set nrOfLis to do JavaScript "document.getElementById('mw-content-text').getElementsByTagName('UL')[" & ws & "].querySelectorAll('li').length;" in document 1
set nrOfLis to nrOfLis - 1 as number
log nrOfLis
repeat with rs from 0 to nrOfLis
delay 0.3
set aShow to do JavaScript "document.getElementById('mw-content-text').getElementsByTagName('UL')[" & ws & "].getElementsByTagName('LI')[" & rs & "].getElementsByTagName('I')[0].getElementsByTagName('A')[0].innerHTML;" in document 1
if aShow is not "" or "missing value" then
copy aShow to end of showsWebList
end if
end repeat
end repeat
end tell
And this works exactly how I want it to. The problem is that it takes 15 minutes until it's done and you gotta have the safari document in front the whole time. So my thought was to pick up the whole code and parse it. Not that easy. This is how my code looks now:
tell application "Safari"
make new document at end of every document
set URL of document 1 to "http://en.wikipedia.org/wiki/List_of_television_programs_by_name"
delay 4
set orgHTML to do JavaScript "document.getElementById('mw-content-text').innerHTML;" in document 1
set orgHTML to orgHTML as text
set readyText to my extractBetween(orgHTML, "<li><i><a ", "</a></i></li>")
log (item 0 of readyText)
set removeArray to my extractBetween(readyText, "href", ">")
set completeArray to {}
repeat with rt from 0 to (count readyText)
repeat with ra from 0 to (count removeArray)
if (item ra of removeArray) is in (item rt of readyText) then
set completeName to trim_line((item rt of readyText), (item ra of removeArray), 1)
set end of completeArray to completeName
end if
end repeat
end repeat
log completeArray
end tell
on extractBetween(SearchText, startText, endText)
set tid to AppleScript's text item delimiters -- save them for later.
set AppleScript's text item delimiters to startText -- find the first one.
set liste to text items of SearchText
set AppleScript's text item delimiters to endText -- find the end one.
set extracts to {}
repeat with subText in liste
if subText contains endText then
copy text item 1 of subText to end of extracts
end if
end repeat
set AppleScript's text item delimiters to tid -- back to original values.
return extracts
end extractBetween
on trim_line(this_text, trim_chars, trim_indicator)
-- 0 = beginning, 1 = end, 2 = both
set x to the length of the trim_chars
-- TRIM BEGINNING
if the trim_indicator is in {0, 2} then
repeat while this_text begins with the trim_chars
try
set this_text to characters (x + 1) thru -1 of this_text as string
on error
-- the text contains nothing but the trim characters
return ""
end try
end repeat
end if
-- TRIM ENDING
if the trim_indicator is in {1, 2} then
repeat while this_text ends with the trim_chars
try
set this_text to characters 1 thru -(x + 1) of this_text as string
on error
-- the text contains nothing but the trim characters
return ""
end try
end repeat
end if
return this_text
end trim_line
Not that smooth and not working. Somehow it seems like I can't get the items out of the list, because it doesn't see it as a list item. Can someone help me out?
Cheers
I would recommend a different approach. DL the source, and then just grab the title between tags. The whole script takes under two seconds. Start with:
property baseURL : "http://en.wikipedia.org/wiki/List_of_television_programs_by_name"
set rawHTML to do shell script "curl '" & baseURL & "'"
set preTag to "\" title=\"" -- " title="
set otid to AppleScript's text item delimiters
set AppleScript's text item delimiters to preTag
set rawList to text items of rawHTML
set nameList to {}
repeat with eachLine in rawList
set theOff to offset of ">" in eachLine
set thisName to text 1 thru (theOff - 2) of eachLine
-- add some error checking here to skip the opening non-title hits, and to fine-tune the precise title string
set nameList to nameList & return & thisName
end repeat
set AppleScript's text item delimiters to otid
return nameList
Add a little error checking, and tweak which preTag and postTag fits best.
I suggest you make use of a specialized 3rd-party tool for this task, which can greatly speed things up.
Here's a solution using the multi-platform web-scraping CLI xidel:
A shell command to demonstrate its brevity and speed (takes less than 1 sec. on my system) - extracts all show names from the page:
xidel -e '//*[#id="mw-content-text"]/ul/li/i/a' https://en.wikipedia.org/wiki/List_of_television_programs_by_name
An equivalent AppleScript snippet - be sure to fill in the path to where you place xidel on your system below:
set targetUrl to "https://en.wikipedia.org/wiki/List_of_television_programs_by_name"
set xPathExpr to "//*[#id=\"mw-content-text\"]/ul/li/i/a"
# Fill in the path to `xidel` on your system here:
set xidelPath to "/path/to/xidel"
# Perform scraping and convert result into an AppleScript list.
set showNames to paragraphs of ¬
(do shell script ¬
quoted form of xidelPath & " -e " & quoted form of xPathExpr & " " & ¬
quoted form of targetUrl)
Here's another solution, use javascript to get the names without any AppleScript loop.
The javascript script takes less than one second to get the names.
tell application "Safari"
make new document at end of every document with properties {URL:"http://en.wikipedia.org/wiki/List_of_television_programs_by_name"}
delay 2 -- in seconds; test for your system
set showsWebList to do JavaScript "var a=new Array();var ul=document.getElementById('mw-content-text').querySelectorAll('UL'); for (var i=1;i<ul.length;i++){li=ul[i].querySelectorAll('LI'); for (var j=0; j< li.length; j++){try {var t=li[j].getElementsByTagName('I')[0].getElementsByTagName('A')[0].innerText; a.push(t)} catch(e) {}}} a;" in document 1
end tell
curl/sed/perl solution:
do shell script "curl 'http://en.wikipedia.org/wiki/List_of_television_programs_by_name' | sed -n '/0-9/,/NewPP/p' | sed -n '/^<li/ s/^.*title=.\\([^\"]*\\).*$/\\1/p' | perl -n -mHTML::Entities -e ' ; print HTML::Entities::decode_entities($_);'"
Here another solution using awk using a very simple script. If the line begins with <li><i> then remove html tags (gsub) and then print it. Then by using every paragraph of the return separated output is converted into a list.
set theURL to "http://en.wikipedia.org/wiki/List_of_television_programs_by_name"
every paragraph of (do shell script "curl " & theURL & " | awk '/^\\<li\\>\\<i\\>/{gsub(\"<[^>]*>\", \"\");print}'")

Unable to manipulate a byte array

I'm trying to pass a byte array from inside my rails app into another ruby script (still inside my rails app), for example:
`./app/animations/fade.sh "\x01\x01\x04\x00" &`
Yields ArgumentError (string contains null byte)
I suppose I'm stumped with how I can form this string and than pass it to my script, which will use it in this sort of fashion:
#sp.write ["#{ARGV[0]}", "f", "\x12"]
I'd like to form the string (on my rails app) like this if possible:
led = "\x01#{led.id}\x04\x00"
But I keep getting ArgumentError (string contains null byte) error. Is there a way I can form this string from elements in my rails app, then pass it to my external script?
You should just pass the data in through standard input, not the command line. You can use IO.popen for this purpose:
IO.popen("./app/animations/fade.sh", "w+") do |f|
f.write "\x01\x01\x04\x00"
end
And on the reading side:
input = $stdin.read
#sp.write [input, "f", "\x12"]
(By the way, it's more common to name Ruby scripts .rb instead of .sh; if fade.sh is meant to be a Ruby script, as I assume from the syntax you used in its example contents, you might want to name it fade.rb)
you could use base64 to pass the bytestring around
$ cat > test.sh
echo $1 | base64 -d
$ chmod a+x test.sh
and then from ruby:
irb
>> require 'base64'
=> true
>> `./test.sh "#{Base64.encode64 "\x01\x01\x04\x00"}"`
=> "\x01\x01\x04\x00"
Can your script accept input from STDIN instead? Perhaps using read.
If you can't do this, you could encode your null and escape your encoding.
E.G. 48656c6c6f0020576f726c64 could be encoded as 48656c6c6f200102020576f726c64
which in turn would be decoded again if both sides agree 2020=20 and 2001=00
Update I think encoding is what you'll have to do because I tried using read and it turns out to be a little too difficult. There's probably another option, but I don't see it yet.
Here's my script and two test runs:
dlamblin$ cat test.sh
echo "reading two lines of input, first line is length of second."
read len
read ans
echo "C string length of second line is:" ${#ans}
for ((c=0; c<$len; c++))
do
/bin/echo -n "${ans:$c:1},"
done
echo ' '
exit
dlamblin$ echo -e '12\0012Hello \0040World' | sh test.sh
reading two lines of input, first line is length of second.
C string length of second line is: 12
H,e,l,l,o, , ,W,o,r,l,d,
dlamblin$ echo -e '12\0012Hello \0000World' | sh test.sh
reading two lines of input, first line is length of second.
C string length of second line is: 5
H,e,l,l,o,,,,,,,,
#Octals \0000 \0012 \0040 are NUL NL and SP respectively

Resources