Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
Can anybody tell me what time format is this 635151121709530000 and how to convert, the result is something like 2013-9-18 14:42:50
Thanks
There's not enough info here to convert your number to a time. There are at least two common ways to represent a point in time:
The first (and most common) is that the number represents a count of units of time between the time represented by the timestamp and some "epoch" date. In order to convert it to a date, you'd need two pieces of info: the scale (the amount of time that elapses between the timestamps N and N+1), and a reference timestamp (commonly the epoch date, which is the date/time that the number 0 represents).
Without that info, you would need at least two timestamps, and the date/time each represents. You could then find the difference between them, divide by the number of seconds, and that'll give you the scale. You could then extrapolate to find the epoch date.
The second possibility is that the number is a bit field, where each part of the date is represented by a certain set of bits in the integer.
If that's the case, then you're somewhat screwed; there could be all kinds of math going on to fit the date parts into a bit field. You will have to either ask someone in charge of the system, or if that's you now, examine the code that generates timestamps.
Edit: If we take the numbers you provided in the comments:
635155956336800000 2013-9-24 05:00:33
635155957368670000 2013-9-24 05:02:16
635155968617830000 2013-9-24 05:21:10
635155968728200000 2013-9-24 05:21:12
635155971811300000 2013-9-24 05:26:21
635155972798800000 2013-9-24 05:27:59
635155978347870000 2013-9-24 05:37:14
Let's see if the numbers make sense as counts.
Take the first and last times and find the difference between their respective timestamps.
635155978347870000 - 635155956336800000 = 22011070000 ticks
Divide by the number of seconds separating the two times ((37*60+14) - 33 == 2201 seconds)
22011070000 ticks / 2201 sec = 10000486.142662 ticks/sec
Round to a nice even number, cause timestamps are based on useful intervals unless you're obfuscating. So in your case, it looks like the scale is 10 million ticks per second, or 100ns per tick.
Verify with the other timestamps (in this case, the 5:27:59 one and the 5:00:33):
635155972798800000 - 635155956336800000 == 16462000000 ticks
16462000000 ticks / 10000000 ticks/sec = 1646.2 sec
(27*60+59) - 33 == 1646 sec
So 100ns looks about right. In order to be sure, though, we'd need timestamps further apart. Just to make sure this is indeed a count rather than, say, two 31-bit numbers representing the year and the current second of that year.
Assuming this is a count, if we take the first timestamp and divide by 10 million:
635155956336800000 ticks / 10000000 ticks/sec = 63515595633.6800000 sec
That's 63.5 billion seconds since the epoch. For reference, 32-bit signed timestamps (which number a bit over 2 billion) will run out in 2038, 68 years from the Unix epoch (1970). This number is about ~29.58 times that, or 29.58 * 68 ~= 2011 years.
That'd put the epoch around the beginning of the first century CE. 1 CE is a significant enough date that it'd make sense as the epoch date. I don't feel like doing the math to confirm that, though.
Corresponding with cHao's 10000000 ticks per second, but using a base date of 01/01/0001 as I'd originally suggested:
$values = array(
array(635155956336800000, "2013-9-24 05:00:33"),
array(635155957368670000, "2013-9-24 05:02:16"),
array(635155968617830000, "2013-9-24 05:21:10"),
array(635155968728200000, "2013-9-24 05:21:12"),
array(635155971811300000, "2013-9-24 05:26:21"),
array(635155972798800000, "2013-9-24 05:27:59"),
array(635155978347870000, "2013-9-24 05:37:14"),
);
function convert($date) {
static $monthArray = array(
31,29,31,30,31,30,31,31,30,31,30,31
);
$date = $date / 10000000 / 24 / 60 / 60;
$y = floor($date / 365.2425);
$YYYY = $y + 1;
$z = 365 * $y + floor($y/4) - floor($y/100) + floor($y/400);
$d = $date - $z;
$month = 1;
while (true) {
$d -= $monthArray[$month - 1];
if ($d < 0) break;
$month++;
$dd = $d;
}
$hh = ($dd - floor($dd)) * 24;
$hours = floor($hh);
$mm = ($hh - floor($hh)) * 60;
$minutes = floor($mm);
$ss = ($mm - floor($mm)) * 60;
$seconds = floor($ss);
return sprintf('%04d-%02d-%02d %02d:%02d:%02d', $YYYY, $month, floor($dd), $hours, $minutes, $seconds);
}
foreach($values as $value) {
echo convert($value[0]), PHP_EOL;
}
gives:
2013-09-22 05:00:33
2013-09-22 05:02:16
2013-09-22 05:21:01
2013-09-22 05:21:12
2013-09-22 05:26:21
2013-09-22 05:27:59
2013-09-22 05:37:14
I'm not sure where the 2-day discrepancy comes from, but the output can probably arbitrarily have 2 days added and unless you're playing with extremely historic dates closer to the 0 timestamp mark, then it'd probably be a good enough function to use
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
I need to calculate a duration and make it human readable.
e.g. I have a string: "2 days 4 hours". I need my code to calculate the duration of that string as a timestamp and to make it human readable.
My problem is that if I add the timestamp to 0, it starts from 1/1/1970, but I need it to just calculate the duration.
I tried to subtract 1/1/1970 01:01:00 to 0 but when calculating it returns a no-sense result.
If I understand you correctly, you would like to transform something like:
$dateString = "2 days 4 hours";
to timestamp?
If that is the case, and you know there will always be days/hours you could do something like:
$dateString = "2 days 4 hours";
preg_match_all('!\d+!', $dateString , $numbersOnly);
$partialTimeStamp= (($numbersOnly[0][0]*24)+$numbersOnly[0][1])*3600;
print_r($partialTimeStamp); // will print 187200
With this you will have a numbers of seconds. If for example you also have minutes in your string you would do:
$dateString = "2 days 4 hours 15 minutes";
preg_match_all('!\d+!', $dateString , $numbersOnly);
$partialTimeStamp= (($numbersOnly[0][0]*24)+$numbersOnly[0][1])*3600 + $numbersOnly[0][2]*60;
print_r($partialTimeStamp); // will print 188100
And with this partial timestamp, you can than calculate next timestamp like:
$nextTimeStamp = time () + $partialTimeStamp;
print_r($nextTimeStamp);
EDIT: Missed the "back to human readable" part..
For this, you would do something like:
$days = floor($partialTimeStamp/ 86400);
$partialTimeStamp = $partialTimeStamp - $days*86400;
$hours = floor($partialTimeStamp/ 3600);
$min = floor($partialTimeStamp/ 60 % 60);
And than just this:
print_r($days." days ".$hours." hours ".$min. " minutes");// will output 2 days 4 hours 15 minutes
I hope this helps.
BR
I have a problem with my script and I dont understand where is the problem. So I have this code :
$i_now = strtotime(date('Y-m-d'));
$i_date_last_bonus = strtotime($o_member->date_last_bonus);
$i_datediff = round(abs($i_now - $i_date_last_bonus) / 86400);
print_r("Date Now :".date('Y-m-d'));
print_r("Last Win :".$o_member->date_last_bonus);
I get the $i_datediff = 1 and I dont understand why because in the print_r I have Date Now :2015-12-04 and Last Win:2015-12-03
Can you help me please where I make the error ? Thx in advance and sorry for my english
In one day there are 24 Hrs, in each hour there are 60Min, in each min there are 60sec. Hence, there are 24*60*60 = 86400sec in one day.
Now, The strtotime() function parses an English textual datetime into a Unix timestamp (the number of seconds since January 1 1970 00:00:00 GMT). Means it returns seconds.
so, i_now = 1449187200 andi_date_last_bonus = 1449100800
Difference is 86400sec.
Now $i_datediff = round(abs($i_now - $i_date_last_bonus) / 86400); this is converting seconds in days.
And Difference is 86400 / 86400 = 1
means 1 day.
This result is correct as you get the number of seconds between two dates first and then you divide it by the number of seconds in 24 hours (86400) which gives you 1 (day) as a result.
I have a variable $route->flighttime which echoes numbers in the following format...
0.5
1.2
1.45
How do I convert it to display HH:MM using echo?
Note: 0.5 is treated by the CMS as 50 minutes for some reason.
Based on OPs comments about the format of his initial time (where .5 is actually 50 minutes), a solution without any math
$time = floatval($route->flighttime);
echo number_format($time,2,':',null);
If the input is a floating point value of hours
First convert the floating point value to hours/minutes:
$hours = floor($route->flighttime);
$minutes = ($route->flighttime - $hours) * 60;
If the input is a hours/minutes pair tortured to fit into a float
You can either multiply by 100 instead of 60, or use this technique which might be more accurate:
list($hours, $minutes) = explode('.', sprintf('%.2F', $route->flighttime));
In any case
Then use printf (or some similar function such as sprintf) to format it properly:
printf("%02d:%02d", $hours, $minutes);
I'm assuming 0.5 means half of an hour. Use gmdate with format G:i and your time in seconds:
echo gmdate('G:i', round($x * 3600));
gmstrftime("%H:%M", $t * 60 * 60);
... where $t is float in hours. Notice use of gmstrftime instead of strftime, becouse you do not want to play with timezones.
If the current format is hour and minutes separated by a dot, you could use DateTime:
$time = DateTime::createFromFormat('G.i', '9.15');
echo $time->format('H:i');
However, in this format, 5 in the minutes section would be 5 minutes, not 50 minutes.
I have created an array with 10 timestamps each 1 day apart:
$data_points = array();
$now = time();
$one_day = 60 * 60 * 24;
for($i = 1; $i <= 10; ++$i) {
$key = $now - ($one_day * $i);
$data_points[$key] = 0;
}
print_r($data_points);
Array
(
[1328642414] => 0
[1328556014] => 0
[1328469614] => 0
[1328383214] => 0
[1328296814] => 0
[1328210414] => 0
[1328124014] => 0
[1328037614] => 0
[1327951214] => 0
[1327864814] => 0
)
Now I have a array of tasks that have started at various times in the last 10 days, I want to see which day my task fell into.
I was going to loop through each $data_point and see if the start time is greater than the current day and less than the next, then increment that data point
is there a better way to do this?
Thanks
Well, to reduce your search time you could put your data into a binary search tree rather than a simple array.
Whether or not that's worth the trouble depends on how big your data set is. Of course, you'd also have to re-balance your tree every so often as you add new dates.
I think there's a better method.
Assuming you have task starting timestamps in an array, the algorithm will be something like :
for each task starting timestamp
timestamp <- $now - timestamp // you will obtain task age in seconds
timestamp <- timestamp / (60*60*24) // you will obtain task age in days
// round resulting timestamp with a precision of 0 if you want to obtain the task age in integer days.
end for each
In this way you will loop on only one array. This will be less expensive than your method.
Obviously, if your tasks come from a SQL database, there will be a greater solution in SQL.
You can use DateTime class
$now = new DateTime();
$task = new DateTime('2012-02-20');
$interval = $taks->diff($now);
echo 'Here is the position you need:' . $interval->format('%R%a days');
** Updated to avoid use of DateTime as asked in comment **
$now = date('Ymd');
$task = date('Ymd',$tasktime);
$interval = $task - $now;
The interval is the number you expect.
I know this question is old, but since there are no accepted answers, and it seems like a fun question to answer - here we go!
Based on your question, your algorithm has the Big O of O(10n) where n is the number of tasks. This means, that it is fairly efficient compared to a lot of things. As pointed out, a binary search tree would be faster having O(log(n)), however implementing it wouldn't really be worth the saved time during processing. Though, you can make it slightly more efficient and have a resulting O(n) by using something like:
$now = time();
$oneDay = 86400; //60 * 60 * 24
foreach($tasks as $task) {
//assuming now that $task is the timestamp of the task
//extra paranthesis added for easier reading
$dif = $now - ($oneDay * ceil(($now - $task) / $oneDay));
$data_points[$dif]++;
}
The math in the diff is as follows. $now-$task is the difference between the two timestamps in seconds, we divide by $oneDay to get the number of days in the past the task occurred. Now, assuming that $now is the start of a new day, and if an event happened just 12 hours ago it was 'yesterday', we use ceil to round it to the next integer so '.5' becomes '1'. From there, we multiply by $oneDay to get the number of seconds of the days that have passed - to work with the $data_points array that you previously created. We then take that result and subtract it from $now, again to work with your $data_points array. That result gives us a time stamp that we can use that matches those in the array you created, and we use it as the 'key' for it and increment accordingly.
This will prevent you from having to loop through the entire $data_points array for each task, and thus reducing its complexity from O(10n) to O(n).
Anyways, I hope that answer helps explain why your formula isn't that inefficient, but shows how to make it ever so slightly more efficient.
I have starting dates and ending dates in my database (MySQL).
How can I get the answer, how many weeks(or days) are inside of those 2 dates? (mysql or php)
For example I have this kind of database:
Started and | will_end
2009-12-17 | 2009-12-24
2009-12-12 | 2009-12-26
...
Update to the question:
How to use DATEDIFF?
How can I make this to work? or should I use DATEDIFF completly differently?
SELECT DATEDIFF('Started ','will_end') AS 'Duration' FROM my_table WHERE id = '110';
If the two columns $d1 and $d2 store unix timestamp obtained from time() then this simple line suffices:
$diffweek = abs($d1 - $d2) / 604800;
Otherwise if the columns are of DATETIME type, then:
$diffweek = abs(strtotime($d1) - strtotime($d2)) / 604800;
p/s: 604800 is the number of seconds in a week (60 * 60 * 24 * 7)
p/s2: you might want to intval($diffweek) or round($diffweek)
Calculating the number of days and dividing by seven won't give you the number of weeks between the two dates. Instead it will return the result of division by 7 that doesn't always correspond to the number of weeks between the two dates when thinking in terms of the number of weeks in the ISO calculation.
For example, given start_date = "2010-12-26" and end_date = "2011-01-25" you will be going through W51,52,01,02,03,04 and those are 6 weeks as per ISO, but if you simply calculate the difference and divide by 7, you'll get 5.
The issue appears when the start date and end date belong to different years.
The best way to do the calculation is to get the last week number of the start_date year and it should refer to the December, 28.
function weeks($ladate2,$ladate3) {
$start_week= date("W",strtotime($ladate2));
$end_week= date("W",strtotime($ladate3));
$number_of_weeks= $end_week - $start_week;
$weeks=array();
$weeks[]=$start_week;
$increment_date=$ladate2;
$i="1";
if ($number_of_weeks<0){
$start_year=date("Y",strtotime($ladate2));
$last_week_of_year= date("W",strtotime("$start_year-12-28"));
$number_of_weeks=($last_week_of_year-$start_week)+$end_week;
}
while ($i<=$number_of_weeks)
{
$increment_date=date("Y-m-d", strtotime($ladate2. " +$i week"));
$weeks[]=date("W",strtotime($increment_date));
$i=$i+1;
}
return $weeks;
}
function diff_weeks($ladate2,$ladate3) {
$weeks=weeks($ladate2,$ladate3);
$diff_weeks=count($weeks);
return $diff_weeks;
}
Best regards,
Manikam
MySQL has datediff which returns the difference in days between two dates, since MySQL 4.1.1.
Do note that, as per the manual, DATEDIFF(expr1,expr2) returns expr1 – expr2 expressed as a value in days from one date to the other. expr1 and expr2 are date or date-and-time expressions. Only the date parts of the values are used in the calculation.
You can use the TO_DAYS function on each date and subtract the two to calculate the difference in days.
DATEDIFF
Find the days and divide by 7
<?php
$dayDif = date('z',strtotime('2009-12-17)') - date('z',strtotime('2009-12-24)');
$numWeeks = $dayDif / 7;
?>
The z option for php's date function gives you the day of the year (0 - 365). By subtracting the two values you find how many days between dates. Then factor by seven for the number of weeks.
Read this page closely, the date() function is rich. http://php.net/manual/en/function.date.php