Date format in float from Persavise db - php

I got data from a Persavive V12 Db. The dates are in a weird format.
They are like float :
Example of date in table : 39787.0
Do someone know this kind of format ? It seems to be the number of days from 1901-01-01.
Since the dates are float, is it possible to add days from a date in PHP ? Like :
$from = '1901-01-01';
$date = date('Y-m-d', strtotime($from .' +'. $float .' days'));
I got always 1970-01-01. Is there another way ?

My first answer so don't hurt me much.
I'm not quite sure what you want to do (put back in the database or perform further operations so I only posted one solution)
The number you posted 39787.0 is a unix timestamp. You need to use mktime to convert what you want to a number (And you need date to convert it to a readable form). Since mktime uses 1901-01-01 as a starting date as well you have to make a couple of changes.
I was a biz lazy and didn't include all the code for all fields but this should allow you modify to add whatever you want (and possibly clean it up to a single line if you want).
I made it in long form so it's easy to read.
<?
$olddate = 39787.0;
$hour = 0;
$min = 0;
$sec = 0;
$month = 0;
$year = 0;
$day = 12;
$month += date("m",$olddate);
$day += date("d",$olddate);
$year += date("Y",$olddate);
$x = date("Ymd",mktime($hour,$min,$sec,$month,$day,$year));
echo $x;
?>

If 39787.0 is in the database, what value is that in a real date (using the application)? If it's 2008-12-05, the it's a VB Date. Do you know what the application was written in? I've seen people use the VB Date data type and store it in an 8 byte float in Btrieve (back in 2003). If it's a VB Date, 1 is 1899-12-31. You should be able to add the number to 1899-12-30 to get the correct date value. Something like:
<?php
$date = new DateTime('1899-12-30');
$date->add(new DateInterval('P39787D'));
echo $date->format('Y-m-d') . "\n";
?>

Related

PHP count time and divide in daytime/nighttime

I have been trying to figure this out for a week now. My wife has started a new taxi-company and she asked me to code a simple webpage for here where she could press a button to save a timestamp, then the press is again when she gets off work, it then creates a second timestamp
I have an MYSQL database with rows containing the start time and stop time. I have managed to use the diff function to see how much time it is between the two timestamps but now comes the tricky part.
Since it's different payments at different times of the day I need to divide the time at a shortened time.
Up to 19:00 she works "daytime" and after that, she works "nighttime" until 06:00 the other day, then there is "weekend daytime" and "weekend nighttime" as well.
So if she creates a timestamp whit the date and time: 2018-08-08 06:30 and then another timestamp at 2018-08-08 21:00, then I need a script that puts these data in ex "$daytimehours = 12" "$daytimeminutes = 30" and "$nighttimehours = 3" "$nighttimeminutes = 0"
I have managed to create a script that almost works, but it is several pages long, and it contains one if-statement for each different scenario daytime-nighttime, nighttime-daytime etc.
So do anyone has a good idea on how to solve this? or maybe just point me in the right direction. I would be happy to pay some money to get this to work.
My solution is
<?php
date_default_timezone_set('Asia/Almaty');
$endDate = '2018-08-08 21:00';
$startDate = '2018-08-08 06:30';
$nightmare = date('Y-m-d 19:00');
$startDay = date('Y-m-d 06:00');
$diffMorning = strtotime($nightmare) - strtotime($startDate);
$diffNight = strtotime($endDate) - strtotime($nightmare);
echo gmdate('H:i', $diffMorning) . "\n"; // this is the difference from start day till 19:00
echo gmdate('H:i', $diffNight); // this is the difference on nightmare
$total = $diffMorning + $diffNight;
echo intval($total/3600) . " hours \n";
echo $total%3600/60 . " minutes \n";
echo $total%3600%60 . ' seconds';
You can check via online compiler
given two dates stated as:
$endDate = '2018-08-08 21:00';
$startDate = '2018-08-08 06:30';
you can use the PHP Date extension to achieve the difference like this:
$start = date_create($startDate);
$end = date_create($endDate);
$boundnight = clone($end);
$boundnight->setTime(19,00);
$total_duration = date_diff($end,$start);//total duration from start to end
$day_duration = date_diff($boundnight,$start);//daytime duration
$night_duration = date_diff($end,$boundnight);// nighttime duration
you can use the format method to print a human readable string this way:
$total_duration=$total_duration->format('%H:%I');
$day_duration=$day_duration->format('%H:%I');
$night_duration=$night_duration->format('%H:%I');
At this step there is nothing left but you say you want to convert each duration in minutes.So let's build a function :
function toMinute($duration){
return (count($x=explode(':',$duration))==2?($x[0]*60+$x[1]):false);
}
Then you can use it this way:
$total_duration = toMinute($total_duration);
$day_duration = toMinute($day_duration);
$night_duration = toMinute($night_duration);
The output of
var_dump($total_duration,$day_duration,$night_duration) at this step is:
int(870)
int(750)
int(120)

date_create_from_format does not give back expected result

I just tried,
date_create_from_format('Ym','201302')
And I guess because it's the 29th today, it's actually giving me back March 1st.
I was hoping to get back 2013-02-01 00:00:00.
Is there a different function that will parse a date "correctly"? If not, I can extract it myself, not a big deal.
If format does not contain the character ! then portions of the generated time which are not specified in format will be set to the current system time.
If format contains the character !, then portions of the generated time not provided in format, as well as values to the left-hand side of the !, will be set to corresponding values from the Unix epoch.
The Unix epoch is 1970-01-01 00:00:00 UTC.
(DateTime Manual)
So, adding a ! at the beginning of your format string should fix your problem.
TheWolf's solution seems to work perfectly, but here's an alternative I started writing anyway:
function CompactStrToTime($str) {
$year = strlen($str)>=4 ? substr($str,0,4) : date('Y');
$month = strlen($str)>=6 ? substr($str,4,2) : 1;
$day = strlen($str)>=8 ? substr($str,6,2) : 1;
$hour = strlen($str)>=10 ? substr($str,8,2) : 0;
$min = strlen($str)>=12 ? substr($str,10,2) : 0;
$sec = strlen($str)>=14 ? substr($str,12,2) : 0;
return mktime($hour,$min,$sec,$month,$day,$year);
}

PHP convert 2 digit year to a 4 digit year

I have data coming from the database in a 2 digit year format 13 I am looking to convert this to 2013 I tried the following code below...
$result = '13';
$year = date("Y", strtotime($result));
But it returned 1969
How can I fix this?
$dt = DateTime::createFromFormat('y', '13');
echo $dt->format('Y'); // output: 2013
69 will result in 2069. 70 will result in 1970. If you're ok with such a rule then leave as is, otherwise, prepend your own century data according to your own rule.
One important piece of information you haven't included is: how do you think a 2-digit year should be converted to a 4-digit year?
For example, I'm guessing you believe 01/01/13 is in 2013. What about 01/01/23? Is that 2023? Or 1923? Or even 1623?
Most implementations will choose a 100-year period and assume the 2-digits refer to a year within that period.
Simplest example: year is in range 2000-2099.
// $shortyear is guaranteed to be in range 00-99
$year = 2000 + $shortyear;
What if we want a different range?
$baseyear = 1963; // range is 1963-2062
// this is, of course, years of Doctor Who!
$shortyear = 81;
$year = 100 + $baseyear + ($shortyear - $baseyear) % 100;
Try it out. This uses the modulo function (the bit with %) to calculate the offset from your base year.
$result = '13';
$year = '20'.$result;
if($year > date('Y')) {
$year = $year - 100;
}
//80 will be changed to 1980
//12 -> 2012
Use the DateTime class, especially DateTime::createFromFormat(), for this:
$result = '13';
// parsing the year as year in YY format
$dt = DateTime::createFromFormat('y', $result);
// echo it in YYYY format
echo $dt->format('Y');
The issue is with strtotime. Try the same thing with strtotime("now").
Simply prepend (add to the front) the string "20" manually:
$result = '13';
$year = "20".$result;
echo $year; //returns 2013
This might be dumbest, but a quick fix would be:
$result = '13';
$result = '1/1/20' . $result;
$year = date("Y", strtotime($result)); // Returns 2013
Or you can use something like this:
date_create_from_format('y', $result);
You can create a date object given a format with date_create_from_format()
http://www.php.net/manual/en/datetime.createfromformat.php
$year = date_create_from_format('y', $result);
echo $year->format('Y')
I'm just a newbie hack and I know this code is quite long. I stumbled across your question when I was looking for a solution to my problem. I'm entering data into an HTML form (too lazy to type the 4 digit year) and then writing to a DB and I (for reasons I won't bore you with) want to store the date in a 4 digit year format. Just the reverse of your issue.
The form returns $date (I know I shouldn't use that word but I did) as 01/01/01. I determine the current year ($yn) and compare it. No matter what year entered is if the date is this century it will become 20XX. But if it's less than 100 (this century) like 89 it will come out 1989. And it will continue to work in the future as the year changes. Always good for 100 years. Hope this helps you.
// break $date into two strings
$datebegin = substr($date, 0,6);
$dateend = substr($date, 6,2);
// get last two digits of current year
$yn=date("y");
// determine century
if ($dateend > $yn && $dateend < 100)
{
$year2=19;
}
elseif ($dateend <= $yn)
{
$year2=20;
}
// bring both strings back into one
$date = $datebegin . $year2 . $dateend;
I had similar issues importing excel (CSV) DOB fields, with antiquated n.american style date format with 2 digit year. I needed to write proper yyyy-mm-dd to the db. while not perfect, this is what I did:
//$col contains the old date stamp with 2 digit year such as 2/10/66 or 5/18/00
$yr = \DateTime::createFromFormat('m/d/y', $col)->format('Y');
if ($yr > date('Y')) $yr = $yr - 100;
$md = \DateTime::createFromFormat('m/d/y', $col)->format('m-d');
$col = $yr . "-" . $md;
//$col now contains a new date stamp, 1966-2-10, or 2000-5-18 resp.
If you are certain the year is always 20 something then the first answer works, otherwise, there is really no way to do what is being asked period. You have no idea if the year is past, current or future century.
Granted, there is not enough information in the question to determine if these dates are always <= now, but even then, you would not know if 01 was 1901 or 2001. Its just not possible.
None of us will live past 2099, so you can effectively use this piece of code for 77 years.
This will print 19-10-2022 instead of 19-10-22.
$date1 = date('d-m-20y h:i:s');

check if datetime from sql is today

I have a date returned from an sql query (a datetime type field) and want to compare it to today's date in PHP. I have consulted php manual and there are many ways to do it. I finally came up with a solution comparing strings, but I would like to know if there are either any 'better' (best practice), cleaner or faster ways to do it. This is my solution:
// $sql_returned_date='2008-10-17 11:20:04'
$today = new DateTime("now");
$f_today=$today->format('Y-m-d'); //formated today = '2011-03-09'
$sql_date=substr($sql_returned_date,0,9); //I get substring '2008-10-17'
if($f_today==$sql_date)
{
echo "yes,it's today";
}else{
echo "no, it's not";
}
thanks
Seriously guys?
//$mysql_date_string= '2013-09-20' OR '2013-09-20 12:30:23', for example
$my_date = new DateTime($mysql_date_string);
if($my_date->format('Y-m-d') == date('Y-m-d')) {
//it's today, let's make ginger snaps
}
You could factor this into the data returned from your database query:
SELECT `DateOnDB`,
DATE(`DateOnDB`) = DATE(CURDATE()) AS isToday
FROM `dbTable`
and simply use PHP to test the value of the isToday column
Excuse me for being a question-digger, but I was trying to achieve the same thing, and I found a simple solution - if you want to select only rows with today's date you can do :
WHERE DATE(datetime_column)=CURDATE()
in your mySQL query syntax.
You'd have three solutions :
Working with strings, like you are doing ; which seems like a solution that works ; even if it doesn't feel clean.
Working with timestamps, using strtotime() and time() ; which is a bad idea : UNIX Timestamps only work for dates that are greater than 1970 and lower than 2038
Working with DateTime everywhere ; which would both work and feel clean.
If I need to make any calculation on the PHP-side, I would probably go with the third solution -- but the first one would be OK in most cases, I suppose.
As a sidenote : instead of formating your date to Y-m-d, you could check if it's :
Greater of equal than today
Less than tomorrow.
If SQL returned date is in this format 2011-03-09 (date format without timing),
$sqlret = "2011-03-05";
$curdate = date('Y-m-d');
echo $diff = strtotime($curdate) - strtotime($sqlret);
echo $no_diff = $diff/(60*60*24);
If the date with time like:
$sqlret = "2011-03-05 12:05:05",
Just make your current date format also like that:
$curdate = date('Y-m-d H:i:s');
If it doesn't satisfies your need, ask your question with some example.
You can use new DateTime php Object that way.
$date1 = new DateTime('2012-01-21');
$date2 = new DateTime ( 'now');
$interval = $date1->diff($date2);
if( $interval->format('%R%a ') == 0){
echo 'it s today';
}
I'd do that:
# SQL
SELECT DATE_FORMAT(date_col, "%Y-%m-%d") AS created_at FROM table
# PHP
if ( date('Y-m-d') == $sql_date ) { // assuming $sql_date is SQL's created_at
echo 'today';
}
$time = //your timestamp
$start = mktime(0,0,0,date("j"),date("n"),date("Y"));
$end = mktime(23,59,0,date("j"),date("n"),date("Y"));
if($time > $start && $time < $end){
//is today
}

Reformat Custom Date in PHP

So I know how to format a date in PHP, but not from a custom format. I have a date that is a string "YYMMDD" and I want to make it "MMDDYYYY'. strtotime doesn't seem like it would do a good job of this when the MM and DD are both low digits.
Use str_split:
$date1 = "YYMMDD";
list($yy, $mm, $dd) = str_split($date1, 2);
// MMDDYYYY format, assuming they are all > 2000
$date2 = $mm . $dd . "20" . $yy;
If you're running PHP >= 5.3, have a look at DateTime::createFromFormat. Otherwise, if you don't want to use pure string manipulation techniques, use the more primitive strptime together with mktime to parse the time into a UNIX timestamp, which you can then format using date.
Maybe I am under-thinking this, but couldn't you just:
$oldDate='040220'; // February 20th, 2004
$year = substr($oldDate, 0,2);
$year += $year &lt 50 ? 2000 : 1900;
$date = preg_replace('/\d{2}(\d{2})(\d{2})/', '$1/$3/'.$year, $oldDate);
And you'd have the string you were looking for, or something close enough to it that you could modify from what I wrote here.
Have many dates prior to 1910? If not, you could check your YY for <=10, and if true, prepend "20" else prepend "19"... Kinda similar approach to MM and DD check for <10 and prepend a "0" if true... (This is all after exploding, or substring... Assign each part to its own variable, i.e. $M=$MM; $D=$DD; $Y=$YYYY; then concatenate/arrange in whatever order you want... Just another potential way to skin the proverbial cat...
Ended up doing:
$expiration_date_year = substr($matches['expiration_date'],0,2);
$expiration_date_month = substr($matches['expiration_date'],2,2);
$expiration_date_day = substr($matches['expiration_date'],4,2);
$expiration_date = date('m/d/Y', mktime(0,0,0,$expiration_date_month, $expiration_date_day, $expiration_date_year));

Categories