GOAL: Add X amount of seconds to existing time stamp (H:i:s) and convert it into a human readable non-military (24:00 Hr) AM/PM time stamp ('3:15 pm'). IF possible, I want to nix the leading zero in instances where timestamp would otherwise read '03:15'.
PROBLEM: All tests return the same results adjusting for variable time added return the same final result: 16:00:00 and/or 04:00 pm
THE ASK: Guidance on where / how my code is failing and how to correct it. I have googled and searched stack, etc. I have run experiments for a few hours and I always get the same result regardless of variables I feed into the test. I have attempted 23 tests and continually returned the same result.
ENVIRONMENT: MAMP, PHP 8.1, Bootstrap
CURRENT RESULT:
01:43:21
1652258601
1652258807
16:00:00 PM
4:00 PM
THE CODE:
$myTIME = '01:43:21';
$staging .= $myTIME . '<br>';
$this_time = strtotime($myTIME);
$staging .= $this_time . '<br>';
$add = rand(23, 218);
$stamp = $this_time + $add;
$staging .= $stamp . '<br>';
$staging .= date("H:i:s A", strtotime($stamp)) . '<br>';
# $stamp = '23:00'; $stamp = new DateTime($stamp); echo $dt->format('h:i A');
$est = date('h:i:s', strtotime($stamp));
$staging .= date( 'g:i A', strtotime( $stamp ) );
$stamp is already an integer/timestamp, so strtotime($stamp) fails. Take that off, and the date will format correctly.
$est = date('h:i:s', $stamp);
I am parsing UserAssist files from Windows registry NTUSER.dat. From the registry I get a field named "Last Executed" which has the explanation "Number of 100 ns intervals since 1.1.1601 UTC+0".
My decimal number is 131955686641390000, and I have to make this to a human readable format. I want to do this by using PHP.
I have figured out that there is a function called add(new DateInterval('XXXX')); that I think I can use, but I need some help to figure out what should be the input to the function. The manual is here; https://www.php.net/manual/en/class.dateinterval.php
This is my code:
$nanoseconds = "131955686641390000";
$date = new DateTime('1601-01-01');
for($i=0;$i<100;$i++) {
$date->add(new DateInterval('P1s'));
}
$date_print = $date->format('Y-m-d H:i:s');
echo"
<p><b>Date:</b> $date_print</p>
";
I tried this but it failed:
$nanoseconds = "131955686641390000";
$seconds = $nanoseconds/1000000000;
$add = "PT" . $seconds . "S";
$date = new DateTime('1601-01-01');
for($i=0;$i<100;$i++) {
$date->add(new DateInterval($add));
}
$date_print = $date->format('Y-m-d H:i:s');
echo"
<p><b>Date:</b> $date_print</p>
";
Fatal error: Uncaught Exception: DateInterval::__construct(): Unknown
or bad format (PT131955686.64139S) in
C:\Users\user\wamp64\www\x.php:257
DateInterval->__construct('PT131955686.641...') #1 {main} thrown in
Unix epoch time is the number of seconds since Jan 1st, 1970. It consists of ten digits.
Your number is in hundreds of nano seconds, so that would work out as 11 digits.
So you can strip off everything after the first 11 digits, and pass that into a DateTime starting in 1601, like so:
<?php
$nano = '131955686641390000';
$seconds = substr($nano, 0, 11);
$date = new DateTime('1601-01-01');
$date->modify('+' . $seconds . ' seconds');
echo $date->format('Y-m-d H:i:s');
Which gives 2019-02-25 11:44:24.
You can see this here https://3v4l.org/fYpSJ
Alternatively, you can subtract the number of seconds being the difference from Jan 1st 1970, to get the same result.
<?php
$nano = '131955686641390000';
$seconds = ((int) substr($nano, 0, 11)) -11644474772;
$date = new DateTime('#' . $seconds);
echo $date->format('Y-m-d H:i:s');
That's a little shorter and cleaner in my opinion. Looks like -11644474772 is a useful number to remember!
I am coding an application where i need to assign random date between two fixed timestamps
how i can achieve this using php i've searched first but only found the answer for Java not php
for example :
$string = randomdate(1262055681,1262055681);
PHP has the rand() function:
$int= rand(1262055681,1262055681);
It also has mt_rand(), which is generally purported to have better randomness in the results:
$int= mt_rand(1262055681,1262055681);
To turn a timestamp into a string, you can use date(), ie:
$string = date("Y-m-d H:i:s",$int);
If given dates are in date time format then use this easiest way of doing this is to convert both numbers to timestamps, then set these as the minimum and maximum bounds on a random number generator.
A quick PHP example would be:
// Find a randomDate between $start_date and $end_date
function randomDate($start_date, $end_date)
{
// Convert to timetamps
$min = strtotime($start_date);
$max = strtotime($end_date);
// Generate random number using above bounds
$val = rand($min, $max);
// Convert back to desired date format
return date('Y-m-d H:i:s', $val);
}
This function makes use of strtotime() as suggested by zombat to convert a datetime description into a Unix timestamp, and date() to make a valid date out of the random timestamp which has been generated.
Another solution using PHP DateTime
$start and $end are DateTime objects and we convert into Timestamp. Then we use mt_rand method to get a random Timestamp between them. Finally we recreate a DateTime object.
function randomDateInRange(DateTime $start, DateTime $end) {
$randomTimestamp = mt_rand($start->getTimestamp(), $end->getTimestamp());
$randomDate = new DateTime();
$randomDate->setTimestamp($randomTimestamp);
return $randomDate;
}
You can just use a random number to determine a random date. Get a random number between 0 and number of days between the dates. Then just add that number to the first date.
For example, to get a date a random numbers days between now and 30 days out.
echo date('Y-m-d', strtotime( '+'.mt_rand(0,30).' days'));
Here's another example:
$datestart = strtotime('2009-12-10');//you can change it to your timestamp;
$dateend = strtotime('2009-12-31');//you can change it to your timestamp;
$daystep = 86400;
$datebetween = abs(($dateend - $datestart) / $daystep);
$randomday = rand(0, $datebetween);
echo "\$randomday: $randomday\n";
echo date("Y-m-d", $datestart + ($randomday * $daystep)) . "\n";
The best way :
$timestamp = rand( strtotime("Jan 01 2015"), strtotime("Nov 01 2016") );
$random_Date = date("d.m.Y", $timestamp );
By using carbon and php rand between two dates
$startDate = Carbon::now();
$endDate = Carbon::now()->subDays(7);
$randomDate = Carbon::createFromTimestamp(rand($endDate->timestamp, $startDate->timestamp))->format('Y-m-d');
OR
$randomDate = Carbon::now()->subDays(rand(0, 7))->format('Y-m-d');
An other solution where we can use date_format :
/**
* Method to generate random date between two dates
* #param $sStartDate
* #param $sEndDate
* #param string $sFormat
* #return bool|string
*/
function randomDate($sStartDate, $sEndDate, $sFormat = 'Y-m-d H:i:s') {
// Convert the supplied date to timestamp
$fMin = strtotime($sStartDate);
$fMax = strtotime($sEndDate);
// Generate a random number from the start and end dates
$fVal = mt_rand($fMin, $fMax);
// Convert back to the specified date format
return date($sFormat, $fVal);
}
Source : https://gist.github.com/samcrosoft/6550473
You could use for example :
$date_random = randomDate('2018-07-09 00:00:00','2018-08-27 00:00:00');
The amount of strtotime in here is WAY too high.
For anyone whose interests span before 1971 and after 2038, here's a modern, flexible solution:
function random_date_in_range( $date1, $date2 ){
if (!is_a($date1, 'DateTime')) {
$date1 = new DateTime( (ctype_digit((string)$date1) ? '#' : '') . $date1);
$date2 = new DateTime( (ctype_digit((string)$date2) ? '#' : '') . $date2);
}
$random_u = random_int($date1->format('U'), $date2->format('U'));
$random_date = new DateTime();
$random_date->setTimestamp($random_u);
return $random_date->format('Y-m-d') .'<br>';
}
Call it any number of ways ...
// timestamps
echo random_date_in_range(157766400,1489686923);
// any date string
echo random_date_in_range('1492-01-01','2050-01-01');
// English textual parsing
echo random_date_in_range('last Sunday','now');
// DateTime object
$date1 = new DateTime('1000 years ago');
$date2 = new DateTime('now + 10 months');
echo random_date_in_range($date1, $date2);
As is, the function requires date1 <= date2.
i had a same situation before and none of the above answers fix my problem so i
Came with new function
function randomDate($startDate, $endDate, $count = 1 ,$dateFormat = 'Y-m-d H:i:s')
{
//inspired by
// https://gist.github.com/samcrosoft/6550473
// Convert the supplied date to timestamp
$minDateString = strtotime($startDate);
$maxDateString = strtotime($endDate);
if ($minDateString > $maxDateString)
{
throw new Exception("From Date must be lesser than to date", 1);
}
for ($ctrlVarb = 1; $ctrlVarb <= $count; $ctrlVarb++)
{
$randomDate[] = mt_rand($minDateString, $maxDateString);
}
if (sizeof($randomDate) == 1)
{
$randomDate = date($dateFormat, $randomDate[0]);
return $randomDate;
}elseif (sizeof($randomDate) > 1)
{
foreach ($randomDate as $randomDateKey => $randomDateValue)
{
$randomDatearray[] = date($dateFormat, $randomDateValue);
}
//return $randomDatearray;
return array_values(array_unique($randomDatearray));
}
}
Now the testing Part(Data may change while testing )
$fromDate = '2012-04-02';
$toDate = '2018-07-02';
print_r(randomDate($fromDate,$toDate,1));
result will be
2016-01-25 11:43:22
print_r(randomDate($fromDate,$toDate,1));
array:10 [▼
0 => "2015-08-24 18:38:26"
1 => "2018-01-13 21:12:59"
2 => "2018-06-22 00:18:40"
3 => "2016-09-14 02:38:04"
4 => "2016-03-29 17:51:30"
5 => "2018-03-30 07:28:48"
6 => "2018-06-13 17:57:47"
7 => "2017-09-24 16:00:40"
8 => "2016-12-29 17:32:33"
9 => "2013-09-05 02:56:14"
]
But after the few tests i was thinking about what if the inputs be like
$fromDate ='2018-07-02 09:20:39';
$toDate = '2018-07-02 10:20:39';
So the duplicates may occur while generating the large number of dates such as 10,000
so i have added array_unique and this will return only the non duplicates
if you use laravel then it's for you.
\Carbon\Carbon::now()->subDays(rand(0, 90))->format('Y-m-d');
Simplest of all, this small function works for me
I wrote it in a helper class datetime as a static method
/**
* Return date between two dates
*
* #param String $startDate
* #param String $endDate
* #return String
*
* #author Kuldeep Dangi <kuldeepamy#gmail.com>
*/
public static function getRandomDateTime($startDate, $endDate)
{
$randomTime = mt_rand(strtotime($startDate), strtotime($endDate));
return date(self::DATETIME_FORMAT_MYSQL, $randomTime);
}
Pretty good question; needed to generate some random sample data for an app.
You could use the following function with optional arguments to generate random dates:
function randomDate($startDate, $endDate, $format = "Y-M-d H:i:s", $timezone = "gmt", $mode = "debug")
{
return $result;
}
sample input:
echo 'UTC: ' . randomDate("1942-01-19", "2016-06-03", "Y-M-d H:i:s", "utc") . '<br>';
//1942-Jan-19 07:00:00
echo 'GMT: ' . randomDate("1942-01-19", "2016-06-03", "Y/M/d H:i A", "gmt") . '<br>';
//1942/Jan/19 00:00 AM
echo 'France: ' . randomDate("1942-01-19", "2016-06-03", "Y F", "Europe/Paris") . '<br>';
//1942 January
echo 'UTC - 4 offset time only: ' . randomDate("1942-01-19", "2016-06-03", "H:i:s", -4) . '<br>';
//20:00:00
echo 'GMT +2 offset: ' . randomDate("1942-01-19", "2016-06-03", "Y-M-d H:i:s", 2) . '<br>';
//1942-Jan-19 02:00:00
echo 'No Options: ' . randomDate("1942-01-19", "2016-06-03") . '<br>';
//1942-Jan-19 00:00:00
readers requirements could vary from app to another, in general hope this function is a handy tool where you need to generate some random dates/ sample data for your application.
Please note that the function initially in debug mode, so change it to $mood="" other than debug in production .
The function accepts:
start date
end date
format: any php accepted format for date or time
timezone: name or offset number
mode: debug, epoch, verbose epoch or verbose
the output in not debug mode is random number according to optional specifications.
tested with PHP 7.x
// Find a randomDate between $startDate and $endDate
function randomDate($startDate, $endDate)
{
// Convert to timetamps
$min = strtotime($startDate);
$max = strtotime($endDate);
// Generate random number using above bounds
$val = rand($min, $max);
// Convert back to date
return Carbon::createFromTimestamp($val);
}
dd($this->randomDate('2014-12-10', Carbon::now()->toString()));
Using carbon
$yeni_tarih = date('Y-m-d', strtotime( '+'.mt_rand(-90,0).' days'))." ".date('H', strtotime( '+'.mt_rand(0,24).' hours')).":".rand(1,59).":".rand(1,59);
Full random date and time
So, we have the following code:
date("Y-m-d",time()+60*365*24*60*60);
The ideea is that I have to make a prognosis and I have the result in number of days which I have to add to the current date. The prognosis is for the year 2060 or past it...in an 64bit environment that works, but on 32bit not so much :)
any ideeas?
10x.
LE:
Ok so I've tried :
$date = new DateTime();
// for PHP 5.3
$date->add(new DateInterval('P20000D'));
// for PHP 5.2
$date->modify('+20000day');
echo $date->format('Y-m-d') . "\n";
and it works
this is working on my 32bit system:
$date = new DateTime("2071-05-26");
echo $date->format('Y-m-d H:i:s');
//i saw this in this question
See this:
http://www.infernodevelopment.com/forum/Thread-Solution-2038-PHP-Date-Bug-Y2-038K-UNIX-TIMESTAMP-BUG
<?php
// Specified date/time in your computer's time zone.
$date = new DateTime('9999-04-05');
echo $date->format('Y-M-j') ."";
// Specified date/time in the specified time zone.
$date = new DateTime('2040-09-08', new DateTimeZone('America/New_York'));
echo $date->format('n / j / Y') . "";
// INPUT UNIX TIMESTAMP as float or bigint from database
// Notice the result is in the UTC time zone.
$r = mysql_query("SELECT date FROM test_table");
$obj = mysql_fetch_object($r);
$date = new DateTime('#'.$obj->date); // a bigint(8) or FLOAT
echo $date->format('Y-m-d H:i: sP') ."";
// OR a constant greater than 2038:
$date = new DateTime('#2894354000'); // 2061-09-19
echo $date->format('Y-m-d H:i: sP') ."";
?>
If you are adding full years/days/months, I suppose you could use simple arithmetic on them individually and then use checkdate() (it claims to work up to year 32767) to validate the result
$date = array('Y' => date('Y'), 'm' => date('n'), 'd' => date('j'));
// +60 years
$date['Y'] += 60;
if (checkdate($date['m'], $date['d'], $date['Y'])) {
$fulldate = implode('-', $date);
}
<?php
// A dirty hack
function bigdate_to_string($t_64bit)
{
$t_base = strtotime('2038-01-01 00:00:00 +0000');
$t_32bit = $t_64bit - $t_base;
return date("Y", $t_32bit) + 68 . date("-m-d H:i:s", $t_32bit);
}
$t_64bit = 130 * 365 * 86400; // November 30, 2099 UTC
echo bigdate_to_string($t_64bit) . "\n";
?>
Output:
susam#swift:~$ php datehack.php
2099-11-30 05:30:00
I am subtracting 68 years from the time and adding it back again while printing the formatted output.
There's a lot of info on doing time zone adjustments in PHP, but I haven't found an answer for specifically what I want to do due to all the noise.
Given a time in one timezone, I want to convert it to the time in another timezone.
This is essentially what I want to do, but I need to be able to do it using only the built-in PHP libs, not PEAR Date.
This is what I've been doing, but it seems to always give me the offset relative to GMT:
$los_angeles_time_zone = new DateTimeZone('America/Los_Angeles');
$hawaii_time_zone = new DateTimeZone('Pacific/Honolulu');
$date_time_los_angeles = new DateTime('2009-09-18 05:00:00', $los_angeles_time_zone);
printf("LA Time: %s<br/>", $date_time_los_angeles->format(DATE_ATOM));
$time_offset = $hawaii_time_zone->getOffset($date_time_los_angeles);
printf("Offset: %s<br/>", $time_offset);
This is the output:
LA Time: 2009-09-18T05:00:00-07:00
Offset: -36000
I was expecting 3 hours (10800 seconds). but the '-7:00' thing tells me it's keeping everything relative to GMT, which maybe explains why it's giving me the "absolute" offset.
How do I just get the offset between the two timezones without all of this GMT hoohah?
Thanks.
UPDATE:
I occured to me that I could do this and get what I want:
$date_time_los_angeles = new DateTime('2009-09-18 05:00:00', $los_angeles_time_zone);
printf("LA Time: %s<br/>", $date_time_los_angeles->format(DATE_ATOM));
$date_time_hawaii = new DateTime('2009-09-18 05:00:00', $hawaii_time_zone);
printf("Hawaii Time: %s<br/>", $date_time_hawaii->format(DATE_ATOM));
$time_offset = $los_angeles_time_zone->getOffset($date_time_los_angeles) - $hawaii_time_zone->getOffset($date_time_los_angeles);
printf("Offset: %s<br/>", $time_offset);
But it feels awkward to me. Anyone know a cleaner way to do it?
Here are a couple of functions using the DateTime classes. The first one will return the difference in seconds between two timezones. The second returns a "translation" of the time from one timezone to another.
function timezone_diff($tz_from, $tz_to, $time_str = 'now')
{
$dt = new DateTime($time_str, new DateTimeZone($tz_from));
$offset_from = $dt->getOffset();
$timestamp = $dt->getTimestamp();
$offset_to = $dt->setTimezone(new DateTimezone($tz_to))->setTimestamp($timestamp)->getOffset();
return $offset_to - $offset_from;
}
function time_translate($tz_from, $tz_to, $time_str = 'now', $format = 'Y-m-d H:i:s')
{
$dt = new DateTime($time_str, new DateTimezone($tz_from));
$timestamp = $dt->getTimestamp();
return $dt->setTimezone(new DateTimezone($tz_to))->setTimestamp($timestamp)->format($format);
}
Demo:
$los_angeles_time = '2009-09-18 05:00:00';
$los_angeles_tz = 'America/Los_Angeles';
$hawaii_tz = 'Pacific/Honolulu';
$los_angeles_hawaii_diff = timezone_diff($los_angeles_tz, $hawaii_tz, $los_angeles_time);
echo $los_angeles_hawaii_diff . '<br />';
$hawaii_time = time_translate($los_angeles_tz, $hawaii_tz, $los_angeles_time);
echo $hawaii_time . '<br />';
As GZipp commented, his code is really only for PHP >= 5.3.0. That is fine, but - here's a version that will work in PHP >= 5.2.0. (Incidentally, it also works in 5.3+, and with 2 less function calls)
<?php
function time_translate($tz_from, $tz_to, $time_str = 'now', $format = 'Y-m-d H:i:s')
{
$dt = new DateTime($time_str, new DateTimezone($tz_from));
$dt->setTimezone(new DateTimezone($tz_to));
return $dt->format($format);
}
$time_diffs = array('now', '-1 hour', '-1 day', '-1 week', '-1 month', '+1 hour', '+1 week', '+1 month');
foreach ($time_diffs as $diff)
{
echo "{$diff}:"
. "\n\t"
. "Current: " . date("Y-m-d H:i:s", strtotime($diff))
. "\n\t"
. "UTC: " . time_translate("US/Eastern", "UTC", $diff)
. "\n\n";
}
Simply minus the first time from the second.
That you'll be able to get the time difference in terms of seconds.