Carbon Difference in Time between two Dates in hh:mm:ss format - date

I'm trying to figure out how I can take two date time strings that are stored in our database and convert it to a difference in time format of hh:mm:ss.
I looked at diffForHumans, but that does give the format I'd like and returns things like after, ago, etc; which is useful, but not for what I'm trying to do.
The duration will never span days, only a max of a couple hours.
$startTime = Carbon::parse($this->start_time);
$finishTime = Carbon::parse($this->finish_time);
$totalDuration = $finishTime->diffForHumans($startTime);
dd($totalDuration);
// Have: "21 seconds after"
// Want: 00:00:21

I ended up grabbing the total seconds difference using Carbon:
$totalDuration = $finishTime->diffInSeconds($startTime);
// 21
Then used gmdate:
gmdate('H:i:s', $totalDuration);
// 00:00:21
If anyone has a better way I'd be interested. Otherwise this works.

$finishTime->diff($startTime)->format('%H:%I:%S');
// 00:00:21

$start = new Carbon('2018-10-04 15:00:03');
$end = new Carbon('2018-10-05 17:00:09');
You may use
$start->diff($end)->format('%H:%I:%S');
which gives the difference modulo 24h
02:00:06
If you want to have the difference with more than 24h, you may use :
$start->diffInHours($end) . ':' . $start->diff($end)->format('%I:%S');
which gives :
26:00:06

I know this is an old question, but it still tops Google results when searching for this sort of thing and Carbon has added a lot of flexibility on this, so wanted to drop a 2022 solution here as well.
TL;DR - check out the documentation for different/more verbose versions of the diffForHumans method, and greater control over options.
As an example, we needed to show the difference between two Carbon instances (start and end) in hours & minutes, but it's possible they're more than 24 hours apart—in which case the minutes become less valuable/important. We want to exclude the "ago" or Also wanted to join the strings with a comma.
We can accomplish all of that, with the $options passed into diffForHumans, like this:
use Carbon\CarbonInterface;
$options = [
'join' => ', ',
'parts' => 2,
'syntax' => CarbonInterface::DIFF_ABSOLUTE,
];
return $end->diffForHumans($start, $options);
Which will result in values like what's seen in the Duration column:
Hope that's helpful for someone!

You can do it using the Carbon package this way to get the time difference:
$start_time = new Carbon('14:53:00');
$end_time = new Carbon('15:00:00');
$time_difference_in_minutes = $end_time->diffInMinutes($start_time);//you also find difference in hours using diffInHours()

Related

Powershell cast string to time only

I have created a Powershell/XAML app, that on button press makes a RESTAPI call, parses the JSON response into fields in the app front end. All fine so far.
These fields will be populated with a string representing a time, so "1800" or "2000" etc.
The user can then change this from 1800 to 1900 for example.
This is all fine, and in the background the app will use 1900 to update a setting to be used in a POST back.
However there are other settings that are offset by 90 mins of the time above. I don't want the user to have update each one, which is why I am trying to programmatically.
But try as I might, I cannot take a string of 1800, add 90 mins to it and make the value 1930 (not 1890).
You could parse the input as a DateTime object (ignoring the date part) and then use the AddMinutes method.
$input = '1800'
$hour = $input.Substring(0,2)
$minute = $input.Substring(2,2)
$dateInputStr = "0001-01-01,${hour}:${minute}:00"
[datetime]$dateInput = ([datetime]$dateInputStr)
$dateInput = $dateInput.AddMinutes(90)
$dateInput.ToString("HHmm")
Using [timespan] instances is another option:
$time = '1800'
([timespan] ($time -replace '(?<=^..)', ':') + '01:30').ToString('hhmm') #->'1930'
$time -replace '(?<=^..)', ':' uses the regex-based -replace operator to insert : after the first two characters - see this regex101.com page for an explanation of the regex and the ability to experiment with it.
Due to expressing the results only in terms of hours and minutes, the calculation wraps around at midnight, so that adding '05:30', for instance, would yield '0030'
The RHS operand needn't be cast to [timespan] directly, because the data type of the LHS - with its explicit [timespan] cast - implicitly converts the RHS to [timespan] too, with '01:30' representing 1 hour and 30 minutes, i.e. 90 minutes.
If you want to define the duration to add in terms of 90 minutes, use the following instead (there are analogous static methods for other units, such as ::FromSeconds():
[timespan]::FromMinutes(90)
Alternatively, you can cast a number to [timespan], which is interpreted as ticks, which are 100-nanosecond units; there are 1e9 (10 to the power of 9) nanoseconds in a second, and therefore 1e7 100-nanosecond units in a second. Thus, multiplying with 1e7 gives you seconds, and multiplying that with 60 minutes.
# 90 minutes expressed as ticks
[timespan] 90 * (60 * 1e7)
When I read this question I wanted to solve it with minimal string manipulation, leaning on time related objects and methods instead. datetime was the first object I thought of, but it expects a date (year, month, day). Things actually simplify if we use timespan. Its static method, ParseExact, can parse the string directly.
$offsetTimeSpan = [timespan]::FromMinutes(90)
$timeField = '830'
$timeStr = $timeField.PadLeft(4, '0')
$timeSpan = [timespan]::ParseExact($timeStr, 'hhmm', [CultureInfo]::InvariantCulture)
$offsetTime = $timeSpan.Add($offsetTimeSpan)
$offsetTime.ToString('hhmm')
$timeField is used to represent the time you get from the RESTAPI. PadLeft is only needed if it's possible for a leading 0 to be missing. ParseExact does the heavy lifting of converting the string to a time type. Because timespan doesn't have an AddMinutes member, we use the Add method passing in a timespan of 90 minutes, $offsetTimeSpan.
You don't mention anything about overflowing past midnight. You can test for overflow using $offsetTime.Days, if any special processing is required.

How to reduce code in Swift when dealing with variables and if statements?

I am currently building an app to teach myself Swift so am still very new. I’ve encountered a problem. The app is a timetable creator. I have up to twelve subjects that all have points. These points are then spread across days. I have a concept for code that will allocate the points fine using loops but wondered whether there was something to reduce the amount of code rather than, what I currently have, something like this for each subject:
subject1.monpts = 20
subject1.tuepts = 20
subject1.wedpts = 20
subject1.thurpts = 20
subject1.fripts = 20
subject1.satpts = 20
subject1.sunpts = 20
This, x12, is a lot of code. But I need it so that each subject has an option for points for each day of the week (which the app will then allocate time based on these points). To print the timetable, I am putting each subjectX.daypts together but this means I’m writing out 12 subjects for each day.
I also need to only display something if the variable actually has a value. I plan to do this using if statements but that means writing a statement for every single variable which at the moment is 12 x 7 = 48! E.g. (ignore the formating - just for concept)
if subjects1.monpts = 0 {
subjects1monLabel = isHidden.false
// or just a print / don't print statement
}
I feel as if I'm missing an easier way to do this!
Here is a picture that explains the concept a bit better:
If you want to save information about those fields you can have a dictionary with keys of a enum and values of ints like so:
enum WeekDay: CaseIterable {
case monday, tuesday, wednesday, thursday, friday, saturday, sunday
}
struct Subject {
var pointsForWeekDay: [WeekDay: Int]
}
Now you could do:
var pointsForWeekDay = Dictionary(uniqueKeysWithValues:
WeekDay.allCases.map { weekDay in
return (weekDay, 20)
}
)
var subject = Subject(pointsForWeekDay: pointsForWeekDay)
CaseIterable allows you to access all values of your enum.
Map takes every weekDay and creates an array of tuples with your Int values.
And finally you can combine that to have a complete Dictionary with uniqueKeysWithValues initializer, which takes an array of the produced tuples.
Your whole vision of how to organize this material is upside down. Start by thinking about what all your subjects have in common: points for each of the seven days, label hidden for each of the seven days, and so forth. Now incorporate that into a type (a struct): Subject. Now instead of subjects1..., subjects2... and so forth, you have an Array of Subject.
So: any time you have variables named with a number, that should be an array instead. Any time you have clumps of repeated concepts, that should be a type instead.
Even the notion of the seven days of the week could itself be condensed in the same way. If all we're talking about is points per day, an array of seven numbers would do.
So we'd end up with a skeleton like this:
struct Subject {
var dayPoints : [Int]
}
var myTwelveSubjects : [Subject]
...and you can build that out as more requirements come online, such as whether a day is hidden.

Formatting a Time value on Ionic 3

I need to find the way to format a time, I tried with angular pipe, but this works with date type values.
I need to be able to remove the seconds to values of the hours shown, example:
1:45:00 change to 1:45 pm or 1:45 p.m. M.
Assuming your date is a instance of Date you can use the built in angular date pipe with the predefined format shortTime or a custom format:
<p> {{date | date:'shortTime'}} </p>
<p> {{date | date:'hh:mm'}} </p>
shortTime is equivalent to 'h:mm a' and will produce results like 9:03 AM.
The custom format 'hh:mm' will produce results like 09:03.
If your date is just a string you could use the built in slice pipe to remove the parts you want to get rid of:
<p> {{"1:45:00" | slice:0:4}} </p>
Which will output 1:45.
Also see this Stackblitz for the different options.
Anyway I'd reccomend using real Date objects or Moment.js objects over bare strings, it makes things a lot easier, especially once you start comparing dates or calculating with dates.
Use Moment.js .here you can convert to any time format
1 - Install via NPM:
npm install moment -S
2 - Import in your Typescript file:
import moment from 'moment';
3 - Use in your Typescript file:
let dateString = "22-04-2017"; //whatever date string u have
let dateObject = moment(dateString, "DD-MM-YYYY").toDate();
If this is format is always the case you can manipulate the string with JavaScript/TypeScript.
myTime = '1:45:00'
showTime() {
var result =
this.myTime.substring(
0, (this.myTime.length - 3) )+ ' pm';
console.log(result);
}
If you have more complicated cases You could use a library like Momentjs.
https://momentjs.com/
This is where you can find what you need in the docs.
https://momentjs.com/docs/#/parsing/string-format/
you can use a custom pipe
transform(timeString: string) {
let time = timeString.slice(0, 5);
let current_hour = timeString.slice(0, 2);
if (parseInt(current_hour) > 12) {
time = time + " PM";
} else {
time = time + " AM";
}
return time;
}

Convert unix time to month number?

Using os.time how can I get how many months have passed since the unix epoch (Unix Timestamp)
I just need it for a month ID, so any kind of number would be fine, as long as it changes every month, and it can be reversed to get the actual month.
local function GetMonth(seconds)
local dayduration,year = 3600*24
local days={31,0,31,30,31,30,31,31,30,31,30,31}
for i=1970,10000 do -- For some reason too lazy to use while
local yeardays = i%4 == 0 and i%100 ~= 0 and 366 or 365
local yearduration = dayduration * yeardays
if yearduration < seconds then
seconds = seconds - yearduration
else
year = i break
end
end
days[2]=(year%4==0) and 29 or 28
seconds = seconds%(365*24*3600)
for i=1,12 do
if seconds>days[i]*dayduration then
seconds=seconds-days[i]*dayduration
else
return --i + year*12 <-- If you want a unique ID
end
end
end
Currently, it'll give the number 2, since it's February. If you uncomment the code at the end for the unique ID, you'll get 554 instead, meaning we're currently at the 554th month since the epoch.
As Jean-Baptiste Yunès said in his answer's comments, I'm not sure if your sentence:
NOTE: This is for Lua, but I'm unable to use os.date
meant you have no os.date, or that you don't know how to use it. You have an answer for both cases, you can use the one you need.
This may do the trick:
print (os.date("*t",os.time())["month"])
os.time() gives you the current date as a number. os.date("*t",...) converts it into a table in which the month equals to the number of the month corresponding to the date.

KRL: Comparing two timestamps

I have two timestamps created with time:now() (one stored in an app variable from the past, one the current time). I need to find the difference between them (preferably in minutes). How do I do that?
I've tried this syntax, but the parser didn't like it:
diff = time:now() - original_time;
time:compare() doesn't give me enough information, and time:add() is the opposite of what I need. There don't seem to be any other applicable time functions documented.
The time functions return a time string, not a time object. To calculate time elapsed, you will have to convert your time string into epoch time (seconds since 1970..). Fortunately, epoch time is one of the formats supported by strftime.
foo = time:now();
efoo = time:strftime(foo,"%s);
The minus operator is actually sensitive to a leading whitespace. It's on the list of things to work out of the parser, but I just haven't had time to get to it. Here is a working rule:
rule first_rule {
select when pageview ".*" setting ()
pre {
foo = time:now();
bar = time:add(foo,{"minutes": -5});
ebar = time:strftime(bar,"%s");
efoo = time:strftime(foo,"%s");
diff = efoo-ebar;
}
notify("-5 minutes in seconds", diff) with sticky = true;
}