Simple, eh? -sigh-
A function. Two string arguments ( I guess it doesn't matter the type). Returning a string which is the time difference between the arguments. Think about it as a counter at your local CS internet-caffe.
function time_diff($start, $stop) {
...
return $diff;
}
echo "Your time playing CS: " . time_diff('19:37', '00:05') . ". Go home!";
I tried. Just too embarrassed to say how much time I've invested in this algorithm.
I can't change the format (tell me about it!).
If you happen to know a class, a file or a piece of code from the depths of the internets, I'd be happy to make use of it.
"Thanks" you very much.
You can't do this correctly unless you know:
The timezone.
The day associated with those times.
Once you know that, you can do:
date_default_timezone_set('timezone here');
$seconds_diff = strtotime("2010-08-29 $end") - strtotime("2010-08-29 $start");
Related
I know this question was probably asked,
however i did not find the answer anywhere.
I would like to determine if the current time is before or after 10:30 AM with php. i found a long way to do it that involves a lot of time parsing. but i am sure there are better ways of doing it.
In this answer it show how to do it if the hour is a whole number (example 2PM)
if( 'now' is larger then 'a given time' ){
}
Use time(), date() and strtotime() functions:
if(time() > strtotime(date('Y-m-d').' 10:30') {
//...
}
Use strtotime(). But remember it accept date object.
if(strtotime(dateobject) > strtotime(dateobject)){
//
}
In My SQL Database I have a Timestamp Column with values like this one representing the Date of the last edit:
2015-01-17 08:55:34.000000
I want to compare the Date with the current date and when is the same day I want to echo Today and otherwise I want to Display the Date of the last edit:
$timefromdb = '2015-01-17 08:55:34.000000'
$edit = strtotime($timefromdb);
if($edit > $_SERVER['REQUEST_TIME']){echo "Today";}
else{
echo strftime("on %A, the %d %B %Y", $edit);
}
echo " at ".date('h:i',$edit)
It always Displays 01/01/1970. There must be a Problem with strtotime. I did a bit of research and it seems like my Timestamp Format isn't a valid one: http://php.net/manual/en/datetime.formats.php
Around the web are a lot of Questions about converting Timestamps but I just can't find the right one: I also got a bit confused by all the functions to convert date stuff.
So can someone Tell me how to get a valid Timestamp for using it in strftime and to compare it to the REQUEST_TIME.
Thanks in Advance!
UPDATE: As Always: The Problem sits in Front of the PC. I declared the Variable but never assgined the Timestamp to it :)
Chop off the .000000 from the date as it makes the date a format strtotime() cannot work with. There's several ways to do this. A simple substr is one of them.
$timefromdb = substr('2015-01-17 08:55:34.000000', 0, -7);
I'm not exactly understood you, but
try
1. compare gettype( $edit ) and gettype($_SERVER['REQUEST_TIME'])
2. not sure what $timefromdb will be more then $_SERVER['REQUEST_TIME'], because IMHO when user edited data, time of it action will me less then current time.
I have a complicated task that I have been beating my head against the wall now for a few days. I've tried about 4 different approaches, however each seems to stall and it is becoming extremely frustrating.
I have a time range. For example, 14:30:00 until 18:30:00. Consider this time range somebody's work shift. During this time range, they state they cannot work from 15:30:00 until 16:30:00 and from 17:30:00 until 18:30:00. I need to modify the original shift's start and end times to remove the conflicting shifts.
The original shift array looks like this:
$original_shift[0]['start'] = '14:30:00';
$original_shift[0]['end'] = '18:30:00';
And the time ranges to be removed from the original shift look like this:
$subshift[0]['start'] = '15:30:00';
$subshift[0]['end'] = '16:30:00';
$subshift[1]['start'] = '17:30:00';
$subshift[1]['end'] = '18:30:00';
Here is a visualization:
So, I basically need my original shift to look like this when I'm done:
$original_shift[0]['start'] = '14:30:00';
$original_shift[0]['end'] = '15:30:00';
$original_shift[1]['start'] = '16:30:00';
$original_shift[1]['end'] = '17:30:00';
Some complications that I also need to consider are:
These time ranges may be any times (not constrained to the half hour as I have used in my example), however I will know with 100% certainty the the unavailable time ranges will always start and end on or in between the original shift's start and end times.
Unavailable times may butt up and/or take the entire original shift's time up.
I'm not looking for someone to "write my code" as much as I am looking for someone who has dealt with something like this in the past and may have some insight on how they accomplished it.
As you specifically asked for "some insight" rather than a full working answer, I'd personally go with arrays populated with "minutes".
$shift = array(
'start' => '15:30:00',
'end' => '18:30:00',
'original' => array(),
'unavailable' => array(),
'modified' => array()
);
You'd then do some jiggery pokery to convert 15:30:00 into 930 and 18:30:00 into 1110 (number of minutes) which will give you the difference between start and end times.
Use range() to quickly fill up the original array, load in your unavailable in a similar format and then use things like array_intersect() and array_diff() to work out which minutes from the original shift are unavailable.
From that, build up the modified array, and read directly from there to your output.
You need to do calculations of time-ranges. As the image shows this seems like a simple subtraction. It would be nice to just have objects that do these.
I had no code for this ready, so the following concept is a bit rough although probably not that bad.
A Range type that represents a time from-to. Those are as DateTime so that the benefits of these existing types can be used. I didn't use much of the benefits so far, however for the rest of the application this can make sense.
The Range type already contains some basic comparison methods I thought were useful to do parts of the calculations.
However as an object can not divide itself into two I also created a Ranges type which can represent one or more Ranges. This was necessary to have something that can be "divided".
I cheated a little here because I implemented the difference calculation as a member of Range, returning an array with one or multiple Range objects. The final calculation then is just having a shift and substract the unavailable ranges from it:
$shift = new Ranges(new DateTime('14:30:00'), new DateTime('18:30:00'));
$unavailables = new Ranges([
new Range(new DateTime('15:30:00'), new DateTime('16:30:00')),
new Range(new DateTime('17:30:00'), new DateTime('18:30:00')),
]);
$shift->subtract($unavailables);
The shift then spans:
14:30:00 - 15:30:00
16:30:00 - 17:30:00
Demo; Gist
I can not say if it is worth the abstraction, what is nice with DateTime objects is that you can compare them with >, < and =. The real benefit from these classes might shed into light when you need more calculations between Range and Ranges. Maybe the interface is not sweet yet, however the basic calculations behind are outlined in the code already.
One caveat: The difference between 14:00-15:00 and 14:00-15:00 in my code will result to 14:00-14:00. I keep the start time to not run empty, but you can run empty, too. The Ranges object should handle it nicely.
The code should speak for itself:
$original_shift[0]['start'] = '14:30:00';
$original_shift[0]['end'] = '18:30:00';
$breaks[0]['start'] = '14:30:00';
$breaks[0]['end'] = '15:30:00';
$breaks[1]['start'] = '16:30:00';
$breaks[1]['end'] = '17:30:00';
$modified_shift = array(
array('start' => $original_shift[0]['start'])
);
for($x = 0, $y = count($breaks), $z = 0; $x < $y; $x++){
$modified_shift[$z]['end'] = $breaks[$x]['start'];
if($modified_shift[$z]['end'] != $modified_shift[$z]['start']){
$z++;
}
$modified_shift[$z]['start'] = $breaks[$x]['end'];
}
$modified_shift[$z]['end'] = $original_shift[0]['end'];
if($modified_shift[$z]['end'] == $modified_shift[$z]['start']){
unset($modified_shift[$z]);
}
I am working on a script that will import some data from a CSV file. As I am doing this I want to be able to check a variable to see if it is a valid date string.
I have seen several ways to check if a sting is a date, but most of them require you to now the format. I will not know the format that the date will in.
right now I am using strtotime(), but this fails to easily
$field ="May";
if(strtotime($field)){
echo "This is a date";
}
In this case, "May" was the persons first name, and not a date at all.
Can any one recommend more reliable function?
Edit based on questions from some of you.
For a variable to pass as a "date" in my case, it would need to be specific to a day/month/year, so just "May" would be to vague to count.
Based on that and Pauls good point below we can also test to see if the string contains a number, such as
$field ="May";
if(strtotime($field) && 1 === preg_match('~[0-9]~', $field)){
echo "This is a date";
}else{
echo "Nope not a date";
}
This seems to cover my immediate needs, but can any one spot any issues or suggest improvements?
Use date_parse and check the values of the returned array
$date = date_parse("May")
// ["year"] == FALSE
// ["month"] == 5
// ["day"] == FALSE
You can also pass those into checkdate.
$date = date_parse($someString);
if ($date["error_count"] == 0 && checkdate($date["month"], $date["day"], $date["year"]))
echo "Valid date";
else
echo "Invalid date";
I don't think there is a all-in-one answer to this problem. You may have different strategy depending on your use case.
Your strtotime() is a perfect solution, but as you say, you may end up with false positive. Why? Because may may be a word or a name. However, what is the result of strtotime('May')?
echo date(DateTime::ISO8601, strtotime('May'));
2012-05-21T00:00:00+0200
So giving only the month will return a date of the current year and the current day starting at midnight with the given month. A possible solution would be to check if your string has the current day and/or the current year included, this way, you may check against to make sure your date is a fully qualified date and valid.
echo date(DateTime::ISO8601, strtotime('May Day')); // (strtotime() returns false)
1970-01-01T01:00:00+0100
echo date(DateTime::ISO8601, strtotime('May 21'));
2012-05-21T00:00:00+0200
A simple strpos() or even a regex should do the trick.
However it is a bit odd and should be used only if you have no other way to do.
I believe that a better solution would be to define a set of valid format and interpolate the result to make sure that the date is valid.
$validDateFormatPatterns = array(
'[0-9]{1,2}-[0-9]{1,2}-[0-9]{4}', // 21-05-2012, obviously this pattern is simple and would accept 05-21-2012,
'the [0-9]{1,2}(th|st|nd|rd) (January|February|...|May|...|December) [0,9]{4}', // The 21st May 2012
);
You should try to cover most of the case and I'm sure you will be able to find regex that checks for most current date format.
In any case, you may need to adapt your function from time to time because there is no easy way to make it bulletproof.
I know this was asked a long time ago, but looking around for this and trying to avoid regex, I came up with this:
function checkInputIsDate($date) {
return (bool)strpbrk($date,1234567890) && strtotime($date);
}
This works because it takes away the issues posted above where only a month is passed into strtotime by making sure there are numbers in the string with strpbrk as well as verifying strtotime outputs a date.
And learned about a function I didn't know existed.
Hope this helps someone.
I was wondering if PHP has a built in function to return the relevance of a date. For example:
$timestamp = time();
$other = time()+86400;
echo rel_date($timestamp); //prints Today
echo rel_date($other); //prints Tomorrow
I know it's pretty simple functionality to build but I don't want to be reinventing the wheel!
As far as I know there is no built in function that has a format option which ouputs "Today", "Yesterday", "Tomorrow", etc..
I've made them myself because of this anyway. It seems you'll need to build it yourself after all, sorry :(