I'm in the process of learning PHP and i'm having some trouble. My function is returning the "milestones" with the same date they were plugged in with. I believe I am using the add() method incorrectly. Thankyou.
PHPplayground: http://www.tehplayground.com/#cARB1wjth
$milestones = null;
$milestones = createMilestone($milestones, true, 10, "15-1-1", "birthday" );
var_dump( $milestones );
function createMilestone($milestones, $forward, $days, $startDate, $milestoneName ){
if ( is_string($startDate)){
$date = DateTime::createFromFormat("Y-m-d", $startDate );
}else if(is_array($startDate) ){
$date = $startDate["date"];
}else{
$date = $startDate;
};
$daysInterval = DateInterval::createFromDateString($days);
if ($forward){
$date->add($daysInterval);
}else{
$date->sub($daysInterval);
}
$milestones[$milestoneName]['date'] = $date;
return $milestones;
}
You need to use :
$daysInterval = DateInterval::createFromDateString($days . ' days');
See the doc here for DateInterval and that page for the diverse date formatting (called relative format) you can use.
And BTW, if you give a DateTime like "15-1-1", the correct format is not "Y-m-d" but "y-m-d" (lowercase 'y')
Related
Am trying to create a date and time function to check if a given dateTime and timezone passed but my function is always returning true even when i put a future date.
I have below example class
<?php
class JobTimer{
public function __construct() {
}
public function isDateTime($startOn, $timezone = "GMT"){
$nowTime = new \DateTime("NOW", new \DateTimeZone($timezone));
$startTime = \DateTime::createFromFormat('M d, Y H:i:s', $startOn, new \DateTimeZone($timezone));
return ($nowTime >= $startTime ? true : false);
}
}
?>
Usage
Everything is returning true, my expectation is to return false if current time based on timezone has not yet elapse or return true when time has elapse or time is now
<?php
$job = new JobTimer();
//if($job->isDateTime("2019-05-02 12:00AM", "Asia/Kuala_Lumpur")){
//if($job->isDateTime("2021-05-02 12:00AM", "Asia/Kuala_Lumpur")){
if($job->isDateTime("2020-05-02 12:00AM", "Asia/Kuala_Lumpur")){
echo "YES";
}else{
echo "NO";
}
?>
In your JobTimer class $startTime is false because your format for DateTime::createFromFormat() does not match the format of the date you are passing in as a parameter and causing it to fail.
M d, Y H:i:s matches May 02, 2020 12:00:00 which is not what you are passing to that class.
You should be using:
$startTime = \DateTime::createFromFormat('Y-m-d H:iA', $startOn, new \DateTimeZone($timezone));
Working code:
class JobTimer{
public function __construct() {
}
public function isDateTime($startOn, $timezone = "GMT"){
$nowTime = new \DateTime("NOW", new \DateTimeZone($timezone));
$startTime = \DateTime::createFromFormat('Y-m-d H:iA', $startOn, new \DateTimeZone($timezone));
return $nowTime >= $startTime;
}
}
$job = new JobTimer();
if($job->isDateTime("2020-05-02 12:00AM", "Asia/Kuala_Lumpur")){
echo "YES";
}else{
echo "NO";
}
Output:
NO
Demo
Change your function to this:
public function isDateTime($startOn, $timezone = "GMT"){
$nowTime = new \DateTime("NOW", new \DateTimeZone($timezone));
$startTime = new \DateTime($startOn, new \DateTimeZone($timezone));
return ($nowTime >= $startTime ? true : false);
}
Your argument passed to createFromFormat is wrong, and therefore not creating a DateTime correctly. You can just pass your $startOn and a DateTimeZone to create a instance of DateTime
I am using meta_box value (YmdHi) and current Date&time to print time difference. And this code work for me.
Now additionally i want to print Live when 2 hours left to start Event.
What mistake I 'm doing to print if or else currently this not work for me?
$then = date( get_post_meta( get_the_ID(), '_start_eventtimestamp', true ) ) ;
$then = new DateTime($then);
$now = new DateTime();
$sinceThen = $then->diff($now);
if ($sinceThen > 2 * HOUR_IN_SECONDS){
echo $sinceThen->d.'days';
echo $sinceThen->h.'hours';
echo $sinceThen->i.'minutes';
}
else{
echo 'LIVE';
}
$sinceThen is a DateInterval (that's what DateTime::diff() returns), so you're comparing a int with an object, which obviously gives you unexpected results. To get the difference in seconds, subtract both DateTime instances' timestamps (which you obtain with DateTime::getTimestamp()):
$then = date( get_post_meta( get_the_ID(), '_start_eventtimestamp', true ) ) ;
$then = new DateTime($then);
$now = new DateTime();
$sinceThen = $then->diff($now);
$sinceThenInSeconds = $then->getTimestamp() - $now->getTimestamp();
if ($sinceThenInSeconds > 2 * HOUR_IN_SECONDS){
echo $sinceThen->d.'days';
echo $sinceThen->h.'hours';
echo $sinceThen->i.'minutes';
}
else{
echo 'LIVE';
}
I made a previous post that was too vague. I've done a lot of research and think I can be more specific.
while (!feof($file_handle))
{
$loansinfo = fgetcsv($file_handle);
// Make sure we only check data for the game we posted
if($loansinfo[0]==$ID) {
$referenceDate = $WantedDate;
$fromDate = "$loansinfo[5]";
$toDate = "$loansinfo[6]";
// Convert dates to timestamps (strings to integers)
$referenceTimestamp = strtotime( $referenceDate );
$fromTimestamp = strtotime( $fromDate );
$toTimestamp = strtotime( $toDate );
$isBetween = $referenceTimestamp >= $fromTimestamp and $referenceTimestamp <= $toTimestamp;
//refuse booking
echo('<script type="text/javascript">alert("Game Already Booked");</script>');
exit;
}
}
// otherwise execute save code
Problem is, I always get 'Game already booked'. Why?
Sample CSV file data as requested:
ID, GameName,GameCost, DaysRequested, Total, ReservationStart, DateEnd
5,Pinball, 3.99,7, 27.99, 01/01/2015, 08/01/2015
Though it should be said that the form requires date entry as YYYY-MM-DD. I have java script that does the conversion.
I've seen this one! Try this:
while (!feof($file_handle)) {
$loansinfo = fgetcsv($file_handle);
if($loansinfo[0]==$ID){
$FromDate = "$loansinfo[5]";
$ToDate ="$loansinfo[6]";
if (strtotime($DateBorrowedFrom) <= strtotime($WantedDate)) {
if(strtotime($ToDate) >= strtotime($WantedDate)){
$CantBook = True;
}
}
else {
if (strtotime($DateBorrowedFrom) <= strtotime($DateTo)) {
$CantBook= true;
}
}
}
}
fclose($file_handle);
if($CantBook = true){
echo('<script type="text/javascript">alert("Game is already Booked");</script>');
}
else{
//Saving the booking
From the look of your code, you are not checking the result of $isBetween.
Here is a modified version that will get you a lot closer, assuming your dates are formatted correctly.
while (!feof($file_handle))
{
$loansinfo = fgetcsv($file_handle);
// Make sure we only check data for the game we posted
if($loansinfo[0]==$ID) {
$referenceDate = $WantedDate;
$fromDate = "$loansinfo[5]";
$toDate = "$loansinfo[6]";
// Convert dates to timestamps (strings to integers)
$referenceTimestamp = strtotime( $referenceDate );
$fromTimestamp = strtotime( $fromDate );
$toTimestamp = strtotime( $toDate );
$isBetween = $referenceTimestamp >= $fromTimestamp and $referenceTimestamp <= $toTimestamp;
if($isBetween == true) {
//refuse booking
echo('<script type="text/javascript">alert("Game Already Booked");</script>');
exit;
}
}
}
I have to tweak this module so that it will not deduct employee's leave when it comes to Saturday, Sunday and public holidays. I have my way around php but I have no idea when it comes to object oriented programming. can anyone explain to me what this block of quote means? especially "$node->frmdate" and "$node->todate"
function leavemgt_update($node) {
if ($node->revision) {
leavemgt_insert($node);
}
else {
$node->frmdate = mktime(0,0,0, $node->frmdate['month'], $node->frmdate['day'],$node->frmdate['year']);
$node->todate = mktime(0,0,0, $node->todate['month'], $node->todate['day'],$node->todate['year']);
$date1 = format_date($node->frmdate, $type = 'custom', $format = 'd/m/Y', $timezone = NULL, $langcode = NULL);
$date2 = format_date($node->todate, $type = 'custom', $format = 'd/m/Y', $timezone = NULL, $langcode = NULL);
$diff= (dateDiff("/",$date2,$date1)+1);
In Drupal, $node is standard Class Object which contains all information about node and every nodes
Basically what I need is an script that, when provided with a time and a timezone can return the time in another time zone.
My main issues are:
Where to get the time offset from GMT from - is there a public database available for this?
How to also take into consideration the daylight saving time (DST) differences as well.
How to nicely wrap it all up inside an PHP class - or is there such a class already available?
<?php
$date = new DateTime('2000-01-01', new DateTimeZone('Pacific/Nauru'));
echo $date->format('Y-m-d H:i:sP') . "\n";
$date->setTimezone(new DateTimeZone('Pacific/Chatham'));
echo $date->format('Y-m-d H:i:sP') . "\n";
?>
The above examples will output:
2000-01-01 00:00:00+12:00
2000-01-01 01:45:00+13:45
found on DateTime Manual on php.net
EDIT:
Like Pekka said: The DateTime class exists from 5.2 on and there you first have to find out which of the methods are realy implemented and which one only exist from 5.3 on.
try this, it might help :)
function converToTz($time="",$toTz='',$fromTz='')
{
// timezone by php friendly values
$date = new DateTime($time, new DateTimeZone($fromTz));
$date->setTimezone(new DateTimeZone($toTz));
$time= $date->format('Y-m-d H:i:s');
return $time;
}
A bit description:
The function takes 3 inputs, time to convert, timezone to convert to, current timezone and returns the output in the specified format.
I know its late. For anyone who would want simple function to convert utc to any local time zone
function UTCTimeToLocalTime($time, $tz = '', $FromDateFormat = 'Y-m-d H:i:s', $ToDateFormat = 'Y-m-d H:i:s')
{
if ($tz == '')
$tz = date_default_timezone_get();
$utc_datetime = DateTime::createFromFormat($FromDateFormat, $time, new
DateTimeZone('UTC'));
$local_datetime = $utc_datetime;
$local_datetime->setTimeZone(new DateTimeZone($tz));
return $local_datetime->format($ToDateFormat);
}
echo UTCTimeToLocalTime('2015-07-01 13:30:00','America/Denver');
To convert from the given timezone to the desired timezone, we just have to add/subtract the difference of timezones (in SECONDS) to given timezone.
$my_timestamp = strtotime("2020-09-22 14:07:26");
/*
Convert timezones difference into seconds
from -7:00 to +5:30 have 12hrs and 30min difference
So in seconds, 12.5*60*60 is equaled to 45000 seconds
*/
$time_zone_difference = 45000;
//Use date function to get datetime in your desired formate
echo date("Y-m-d h:i:sa", $my_timestamp + time_zone_difference );
or we can write it like
Below given functions are for additional help.
Convert timezone differences in seconds, (which you can hardcode, if it is fixed throught the project):
function timezoneDifferenceInSec( $source_timezone, $required_timezone){
$a = explode(":",$source_timezone);
$b = explode(":",$required_timezone);
$c = (intval($a[0])*60+intval($a[1]))*60;
$d = (intval($b[0])*60+intval($b[1]))*60;
$diffsec =0;
if($c < $d)
$diffsec = $d-$c;
else
$diffsec = $c-$d;
return $diffsec;
}
//function call
$differenc = timezoneDifferenceInSec("-07:00", "+05:30");
Function to convert DateTime into required Timezone (if difference is known):
//datetime in String and timezone_differe is in int
function convertTimezone( $source_date_time, $timezone_diff_in_sec){
return date("Y-m-d h:i:sa", strtotime($source_date_time) + $timezone_diff_in_sec);
}
//function call
$timestamp = "2020-09-22 14:07:26";
$timezone_difference = 4500; //ie from -07:00 to +05:30
echo convertTimezone( $timestamp, $timezone_difference);
Function to convert DateTime into required Timezone (if difference in seconds among the timezones is known):
example: Timestamp give is "2020-09-22 14:07:26".
Timezones difference in seconds id 4500; //ie from -07:00 to +05:30
// timestamp as in String and timezones_diff_in_sec is in int
function convertTimezone( $timestamp, $timezones_diff_in_sec){
return date("Y-m-d h:i:sa", strtotime($source_date_time) + $timezones_diff_in_sec);
}
Function call (
//function call
$timestamp = "2020-09-22 14:07:26";
$timezone_difference = 4500; //ie from -07:00 to +05:30
echo convertTimezone( $timestamp, $timezone_difference);
Here i use this function for converting datetime into another timezone.
For best result if you convert your datetime into utc timezone and then convert into required timezone then it is better result for it.
function ConvertTimezoneToAnotherTimezone($time, $currentTimezone, $timezoneRequired) {
$dayLightFlag = false;
$dayLgtSecCurrent = $dayLgtSecReq = 0;
$system_timezone = date_default_timezone_get();
$local_timezone = $currentTimezone;
date_default_timezone_set($local_timezone);
$local = date("Y-m-d H:i:s");
/* Uncomment if daylight is required */
// $daylight_flag = date("I", strtotime($time));
// if ($daylight_flag == 1) {
// $dayLightFlag = true;
// $dayLgtSecCurrent = -3600;
// }
date_default_timezone_set("GMT");
$gmt = date("Y-m-d H:i:s ");
$require_timezone = $timezoneRequired;
date_default_timezone_set($require_timezone);
$required = date("Y-m-d H:i:s ");
/* Uncomment if daylight is required */
// $daylight_flag = date("I", strtotime($time));
// if ($daylight_flag == 1) {
// $dayLightFlag = true;
// $dayLgtSecReq = +3600;
// }
date_default_timezone_set($system_timezone);
$diff1 = (strtotime($gmt) - strtotime($local));
$diff2 = (strtotime($required) - strtotime($gmt));
$date = new DateTime($time);
$date->modify("+$diff1 seconds");
$date->modify("+$diff2 seconds");
if ($dayLightFlag) {
$final_diff = $dayLgtSecCurrent + $dayLgtSecReq;
$date->modify("$final_diff seconds");
}
$timestamp = $date->format("Y-m-d H:i:s ");
return $timestamp;
}
Thank You.