I would like to make custom timestamps. I need to round the minute of the time to 00 or 30. I made already a PHP code for this:
if (date("i") >= '15' && date("i") < '45') {
$minute = "30";
}
else {
$minute = "00";
}
But, now, I want to make the timestamp with the time + date in it.
Does someone have a solution for this? I think I'll need to use strptime but I don't know how exactly..
You can use mktime to generate a timestamp rounded to the nearest 30 minutes:
echo date('Y-m-d H:i:s', mktime(date('H'), round(date('i') / 30) * 30, 0));
Example here:
http://codepad.org/3NCeWO21
The following code snippet:
<?php
date_default_timezone_set('America/New_York');
$format = '%d/%m/%Y %H:%M:%S';
$strf = strftime($format);
print_r(strptime($strf, $format));
?>
Produces this output:
Array
(
[tm_sec] => 49
[tm_min] => 48
[tm_hour] => 8
[tm_mday] => 14
[tm_mon] => 3
[tm_year] => 113
[tm_wday] => 0
[tm_yday] => 0
[unparsed] =>
)
I think you can take it from here.
Related
The following code works if I manually type in every day for every single month in each hard coded array.
I then loop through the arrays for a match and if I find it, I return the first index and the last index value of that array. These are the pay period start and end dates later to be used with mysql select queries.
// MOUNTAIN DAYLIGHT SAVINGS TIME
date_default_timezone_set('MST7MDT');
// = PHP Default TimeZone
//print 'MOUNTAIN DAYLIGHT SAVINGS TIME';
//print '<p>';
// = MySQL CURRDATE() in MySQL DATETIME Format.
$php_current_date = date('Y-m-d');
// 2019 Pay Periods - MONTHLY
$parent_array = array(
1 => array('2019-01-01','2019-01-31'),
2 => array('2019-02-01','2019-02-28'),
3 => array('2019-03-01','2019-03-31'),
4 => array('2019-04-01','2019-04-30'),
5 => array('2019-05-01','2019-05-31'),
6 => array('2019-06-01','2019-06-30'),
7 => array('2019-07-01','2019-07-31'),
8 => array('2019-08-01','2019-08-31'),
9 => array('2019-09-01','2019-09-30'),
10 => array('2019-10-01','2019-10-31'),
11 => array('2019-11-01','2019-11-30'),
12 => array('2019-12-01','2019-12-31'),
13 => array('2020-01-01','2020-01-31'),
14 => array('2020-02-01','2020-02-29'),
15 => array('2020-03-01','2020-03-31'),
16 => array('2020-04-01','2020-04-30'),
17 => array('2020-05-01','2020-05-31'),
18 => array('2020-06-01','2020-06-30'),
19 => array('2020-07-01','2020-07-31'),
20 => array('2020-08-01','2020-08-31'),
21 => array('2020-09-01','2020-09-30'),
22 => array('2020-10-01','2020-10-31'),
23 => array('2020-11-01','2020-11-30'),
24 => array('2020-12-01','2020-12-31')
);
$current_pay_period_start = '';
$current_pay_period_end = '';
// For each child Array of date Strings inside parent Array of arrays...
foreach($parent_array as $child_array){
// Speculate the variable name as $result_found while searching each child Array of date Strings
// for the Current date in *Mountain Daylight Savings Time
$result_found = in_array($php_current_date, $child_array);
// if we have a match...
if ($result_found) {
// GET LEFT-MOST index and assign it to a variable.
$current_pay_period_start = current($child_array);
// GET RIGHT-MOST index and assign it to another variable.
$current_pay_period_end = end($child_array);
// Add a day for mysql query logic...
// because mysql uses < instead of =< for comparison in the query the follows...
$current_pay_period_end = date('Y-m-d', strtotime($current_pay_period_end . ' + 1 days'));
/*
Following Works ONLY on direct access.
Debug Only.
Eg. localhost/folder/filename.php
*/
print 'Php Current Date: ' . $php_current_date;
print '<br>';
print 'Current Pay Period Start: ' . $current_pay_period_start;
print '<br>';
print 'Current Pay Period End: ' . $current_pay_period_end;
exit;
}
}
I have tried to implement the solution below but, I keep getting errors related to me not being able to compare date strings... It seems I have learned to find date strings in an array of arrays but they aren't really dates as far as php is concerned.
/**
* #param DateTime $date Date that is to be checked if it falls between $startDate and $endDate
* #param DateTime $startDate Date should be after this date to return true
* #param DateTime $endDate Date should be before this date to return true
* return bool
*/
function isDateBetweenDates(DateTime $date, DateTime $startDate, DateTime $endDate) {
return $date > $startDate && $date < $endDate;
}
$fromUser = new DateTime("2012-03-01");
$startDate = new DateTime("2012-02-01 00:00:00");
$endDate = new DateTime("2012-04-30 23:59:59");
echo isDateBetweenDates($fromUser, $startDate, $endDate);
Here's how I try to call it and get the error...
isDateBetweenDates($php_current_date, $current_pay_period_start, $current_pay_period_end);
I have wrote the following for you, that compares the two dates from your array. Hopefully it will help!
$php_current_date = date('Y-m-d');
$parent_array = array(
1 => array('2019-01-01','2019-01-31'),
2 => array('2019-02-01','2019-02-28'),
3 => array('2019-03-01','2019-03-31'),
4 => array('2019-04-01','2019-04-30'),
5 => array('2019-05-01','2019-05-31'),
6 => array('2019-06-01','2019-06-30'),
7 => array('2019-07-01','2019-07-31'),
8 => array('2019-08-01','2019-08-31'),
9 => array('2019-09-01','2019-09-30'),
10 => array('2019-10-01','2019-10-31'),
11 => array('2019-11-01','2019-11-30'),
12 => array('2019-12-01','2019-12-31'),
13 => array('2020-01-01','2020-01-31'),
14 => array('2020-02-01','2020-02-29'),
15 => array('2020-03-01','2020-03-31'),
16 => array('2020-04-01','2020-04-30'),
17 => array('2020-05-01','2020-05-31'),
18 => array('2020-06-01','2020-06-30'),
19 => array('2020-07-01','2020-07-31'),
20 => array('2020-08-01','2020-08-31'),
21 => array('2020-09-01','2020-09-30'),
22 => array('2020-10-01','2020-10-31'),
23 => array('2020-11-01','2020-11-30'),
24 => array('2020-12-01','2020-12-31')
);
foreach ($parent_array as $child_array) {
//compare dates using strtotime, did the conversion in the if statement to retain the original date format, for output if results are found.
if (strtotime($php_current_date) >= strtotime($child_array[0]) && strtotime($php_current_date) <= strtotime($child_array[1])) {
// match found...
$current_pay_period_start = $child_array[0];
$current_pay_period_end = $child_array[1];
print 'Php Current Date: ' . $php_current_date;
print '<br>';
print 'Current Pay Period Start: ' . $current_pay_period_start;
print '<br>';
print 'Current Pay Period End: ' . $current_pay_period_end;
exit;
}
}
I have tested it and the following is outputted:
Php Current Date: 2019-03-07
Current Pay Period Start: 2019-03-01
Current Pay Period End: 2019-03-31
Hopefully this will help!
I need to loop dates, according to different $eventname. I was already able to write a script that adds one week to the original date, but I don't know how I can loop it for a defined time.
code used:
$eventname = $event->title;
// TODO: loop for specified times if $eventname contains definded strings
$start_date = helper('com://site/ohanah.date.format', array(
'date' => $event->start,
'format' => 'Y/m/d H:i',
'timezone' => 'UTC'
));
$date = strtotime($start_date) + 604800;
echo "<pre>";
echo date('d. F Y, H:i', $date);
echo ' - ';
echo helper('com://site/ohanah.date.format', array(
'date' => $event->end,
'format' => 'H:i',
'timezone' => 'UTC'
));
echo "</pre>";
Output: (start date would be one week before) 18. April 2018, 14:00 - 16:00
So my question is, how can I loop this that the output is e.g. 6 times with one week space between each of them?
When working with dates and times, do not add seconds to timestamps or something like that, because it will get you in trouble in leapyears and daylight saving times, because one day is not always 86400 seconds.
Better use PHP's DateTime and DateInterval classes.
<?php
$Date = new DateTime("2018-03-03 14:00:00");
for($i=0;$i<6;$i++) { //loop 6 times
$Date->add(new DateInterval('P1W')); //add one week
echo $Date->format("Y-m-d H:i:s").PHP_EOL;
}
Output:
2018-03-10 14:00:00
2018-03-17 14:00:00
2018-03-24 14:00:00
2018-03-31 14:00:00
2018-04-07 14:00:00
See also:
http://php.net/manual/en/class.datetime.php
http://php.net/manual/en/class.dateinterval.php
Something like that?
<?php
$oneWeek = 604800;
$date = '2018-04-05';
$dates = array($date);
for ($i = 0; $i < 6; $i++) {
$dates[] = $date = date('Y-m-d', strtotime($date) + $oneWeek);
}
var_dump($dates);
I am not entirely sure I understand the question, but it looks like you want to have a condition that will either set a specific number of times for the output loop or determine whether the loop is ran that number of times.
If so, you can set a counter variable with your condition, then run the loop that number of times, defaulting the counter variable to 1 in the case that you do not want to output more than one time:
$eventname = $event->title;
// TODO: loop for specified times if $eventname contains definded strings
$counter = (/*your condition for $eventname*/) ? 6 : 1;
for ($x = 0; $x < $counter; $x++) {
$start_date = helper('com://site/ohanah.date.format', array(
'date' => $event->start,
'format' => 'Y/m/d H:i',
'timezone' => 'UTC'
));
$date = strtotime($start_date) + 604800;
echo "<pre>";
echo date('d. F Y, H:i', $date);
echo ' - ';
echo helper('com://site/ohanah.date.format', array(
'date' => $event->end,
'format' => 'H:i',
'timezone' => 'UTC'
));
echo "</pre>";
}
I've got bunch of birthdays which are stored in format DDMMMYY. I need to convert those to date values, so i can store those in database.
Is there any easy way of telling strtotime function that date must be in the past?
<?php
$datestring = '22SEP41';
echo date('Y-m-d',strtotime($datestring)); //outputs 2041-09-22, should be 1941-09-22
?>
<?php
$datestring = '22SEP41';
$matches = [];
preg_match('/([0-9]{2})([A-Z]{3})([0-9]{2})/', $datestring, $matches);
$prefix = ($matches[3] <= date('y') ? '20' : '19');
$matches[3] = "{$prefix}{$matches[3]}";
$ts = strtotime("{$matches[1]} {$matches[2]} {$matches[3]}");
// date ('Y-m-d', $ts) == 1941-09-22
This assumes that 22SEP06 should be interpreted as 2006 rather than 1906 - basically it gives the output a range of 1917 -> 2016.
This method create a date of past century only if standard evaluated date is after today:
$date = date_create( $datestring );
if( $date->diff( date_create() )->invert )
{
$date->modify( '-100 years' );
}
echo $date->format( 'Y-m-d' );
For
$datestring = '22SEP41';
the output is:
1941-09-22
For
$datestring = '22SEP01';
the output is:
2001-09-22
eval.in demo
Basically, we create a DateTime based on given string, then we calculate difference with current day; if the difference is negative (->invert), we subtract 1 century from the date.
You can personalize the condition using ->format('%R%Y') instead of ->invert. In this example:
if( $date->diff( date_create() )->format('%R%Y') < 10 )
Dates from 00 through 05 as evaluated as 2000-2005.
You could try something like:
$ds = '22SEP41';
$day = $ds[0].$ds[1];
// Getting the month.
$mon = array(
'JAN' => 1,
'FEB' => 2,
'MAR' => 3,
'APR' => 4,
'MAY' => 5,
'JUN' => 6,
'JUL' => 7,
'AUG' => 8,
'SEP' => 9,
'OCT' => 10,
'NOV' => 11,
'DEC' => 12
);
$mont = $ds[2].$ds[3].$ds[4];
$month = $mon[$mont]; // Gets the month real.
$year = '19'.$ds[5].$ds[6];
$final = $day.'-'.$month.'-'.$year;
I tested it on my local machine and it worked. Hope it works and is what you're looking for :)
Let say I have array like this :
Array (
[2015-03-14] => 3
[2015-05-23] => 10
[2015-06-21] => 7
[2015-05-24] => 3
[2015-06-27] => 10
[2015-06-29] => 7
)
Explanations :
The Key is for DATE and there are several different months and days ( 03 = March, 05 = May, etc )
Questions
How to count total of value based on the Key, for example someone set the date range field ( in frontend page ) and will get the total value from Key 2015-03-14 to 2015-06-27 ?
Or, is there any others method to make it more simple?
If you know your keys will always be dates, you can construct date objects using your keys and use date comparisons.
<?php
$arr = array(
'2015-03-14' => 3,
'2015-05-23' => 10,
'2015-06-21' => 7,
'2015-05-24' => 3,
'2015-06-27' => 10,
'2015-06-29' => 7,
);
$rangeStart = date('2015-03-14');
$rangeEnd = date('2015-06-27');
$sum = 0;
foreach ($arr as $key=>$value) {
$d = date($key);
if ($d >= $rangeStart && $d <= $rangeEnd) {
$sum += $arr[$key];
}
}
echo $sum;
First thing I have to ask, is do you have access to an SQL interface to get this information? Things like this are much better handled by SQL. The resulting code would perform better, be easier to understand and easier to write if you could just select only the entries you need from the database from the start.
Depending on your schema, the code might look like this (assuming PDO which you SHOULD be using):
$stmt = $db->prepare("
SELECT SUM(your_count_field)
FROM your_table
WHERE your_date_field BETWEEN '?' AND '?'
");
$result = $stmt->execute([$date_start, $date_end]);
In the absence of that, I don't think there's an easy way. #mittmemo has a pretty good solution, but I wouldn't use it if you have to select from more than 100 entries or so, or if you will one day need that kind of capacity.
If using PHP 5.6 or more,
$input = [
'2015-03-14' => 3,
'2015-05-23' => 10 ,
'2015-06-21' => 7 ,
'2015-05-24' => 3,
'2015-06-27' => 10 ,
'2015-06-29' => 7
];
$start_date = '2015-05-23';
$end_date = '2015-06-29';
$sum = array_sum(array_filter($input, function($date) use ($start_date, $end_date){
return ( ( $date >= $start_date ) && ( $date <= $end_date ) );
}, ARRAY_FILTER_USE_KEY));
I have an offset from UTC stored in minutes: e.g -240
I'm trying to find the corresponding UNIX timestamp of midnight of the current day for this particular offset.
I found similar information in questions like this one: How do I get the UTC time of "midnight" for a given timezone?
However, I don't have the city name/timezone jurisdiction, just a minute offset. I think this should be fine since for my purposes I don't need to account for daylight savings, it can be off by an hour and still be fine.
Examples
Offset: -420
Midnight on 7/12/2014: 1405148400 (unix TS)
With UTC, I would have to first tell if it's the next day or same day as the TZ because it may have a different "last midnight".
While this solution looks a little ugly it does do what I think you're asking for! This example uses -180 minutes as the offset.
date_default_timezone_set('UTC');
// Work out which day the time zone is in
$day = strtotime('-180 minutes');
// Strip of the time part of the day, to give UTC midnight on the correct day
$utcMidnight = strtotime('midnight', $day);
// Now apply the offset in reverse to give the zone's midnight
$zoneMidnight = strtotime('+180 minutes', $utcMidnight);
You could use date_default_timezone_set to make all time-related functions acknowledge the shift. First thing to do is to convert those minutes into hours, since the UTC gap is 1 hour between n and n+1.
$hours = $minutes / 60;
I would also recommend that you check the minutes values first :
if($minutes % 60 == 0) // We're good.
Now, if you want to convert the UTC offset to a timezone, you can create your function :
<?php
function offsetToTimezone($offset){
$timezones = array(
"-12" => "Pacific/Kwajalein",
"-11" => "Pacific/Samoa",
"-10" => "Pacific/Honolulu",
"-9" => "America/Juneau",
"-8" => "America/Los_Angeles",
"-7" => "America/Denver",
"-6" => "America/Mexico_City",
"-5" => "America/New_York",
"-4" => "America/Caracas",
"-3.5" => "America/St_Johns",
"-3" => "America/Argentina/Buenos_Aires",
"-2" => "Atlantic/Azores",
"-1" => "Atlantic/Azores",
"0" => "Europe/London",
"1" => "Europe/Paris",
"2" => "Europe/Helsinki",
"3" => "Europe/Moscow",
"3.5" => "Asia/Tehran",
"4" => "Asia/Baku",
"4.5" => "Asia/Kabul",
"5" => "Asia/Karachi",
"5.5" => "Asia/Calcutta",
"6" => "Asia/Colombo",
"7" => "Asia/Bangkok",
"8" => "Asia/Singapore",
"9" => "Asia/Tokyo",
"9.5" => "Australia/Darwin",
"10" => "Pacific/Guam",
"11" => "Asia/Magadan",
"12" => "Asia/Kamchatka"
);
return $timezones[$offset];
}
?>
... and use if for conversion :
date_default_timezone_set(offsetToTimezone($hours));
By the way, I suggest you have a look at this answer, which provides you with a more elegant way to achieve the work of offsetToTimezone.
Now that your script if configured on the correct timezone, just ask for a timestamp :
$timestamp = mktime(0, 0, 0);
If at some time, you need to reset to timezone to default, you might need date_default_timezone_get to save it :
$timezone = date_default_timezone_get();
// Change to another timezone based on your offset.
// Get your timestamp.
date_default_timezone_set($timezone);
I had to think through it quite a bit, but I think this was the solution I was looking for. Let me know if you think this algorithm is incorrect.
function getLastMidnightForOffset( $minuteOffset ) {
$today = mktime( 0, 0, 0 );
$tomorrow = $today + 86400;
$yesterday = $today - 86400;
$offset = $minuteOffset * 60;
if ( time() + $offset >= $tomorrow ) {
$localMidnight = $tomorrow - $offset;
} elseif ( time() + $offset >= $today ) {
$localMidnight = $today - $offset;
} else {
$localMidnight = $yesterday - $offset;
}
return $localMidnight;
}