How to convert the time to minutes of Timer - flutter

I have this time that starts when a product is initialized and I want to format it to 00:00 instead of just 0.
Timer _timer;
_startTimer(prod) {
prod.tempo = 0;
_timer = Timer.periodic(Duration(seconds: 1), (timer) {
setState(() {
prod.tempo++;
});
});
}`
[you can se the time in red I want to convert][1]
[1]: https://i.stack.imgur.com/vCv7p.jpg

If you have a total number of seconds, you can pretty print it with:
String toTimeField(int n) => n.toString().padLeft(2, '0');
var seconds = totalSeconds % 60;
var minutes = totalSeconds ~/ 60;
var prettyDuration = '${toTimeField(minutes)}:${toTimeField(seconds)}`;
That said, if you want to measure a duration, you're usually better off keeping track of the starting time and then computing the difference with the current time. That prevents accumulating error if there are any timing discrepancies from when your callback fires. You can use DateTime.now() to get the current time, store it, and then when your callback fires, call DateTime.now() again and subtract the original value. Or use the Stopwatch class, which does that for you. Using Stopwatch and Duration, you'd do:
_startTimer(prod) {
prod.stopwatch = Stopwatch();
...
}
...
final elapsed = prod.stopwatch.elapsed;
var seconds = elapsed.inSeconds % 60;
var minutes = elapsed.inMinutes;
Finally, I also recommend avoiding using : when printing durations since it could easily be misinterpreted. Does 12:34 represent a time? Does it represent 12 hours and 34 minutes or 12 minutes and 34 seconds? Printing durations as 12m34s is much clearer.

You can format the String as follows:
var seconds = prod.tempo % 60;
var minutes = (prod.tempo - seconds) / 60;
//if you have less than 10 seconds/minutes, prepend a '0':
String secondsAsString = seconds < 10 ? '0$seconds' : seconds;
String minutesAsString = minutes < 10 ? '0$minutes' : minutes;
String displayTime = 'Tempo: ' + secondsAsString + ':' + minutesAsString;

Related

Dart | Convert seconds to DateTime without calculate

Sometimes we need day, hour, minute, second to countdown, but what we know just second.
For example:
1s -> 0day 0hour 0minute 1s
10s -> 0day 0hour 0minute 10s
100s -> 0day 0hour 1minute 40s
Here is my solution:
void _test() {
var diffseconds = 100;
var seconds = diffseconds % 60;
var minute = diffseconds ~/ 60 % 60;
var hour = diffseconds ~/ 60 ~/ 60 % 24;
var day = diffseconds ~/ 60 ~/ 60 ~/ 24;
print('day=$day');
print('hour=$hour');
print('minute=$minute');
print('second=$seconds');
}
If I can change second to DateTime, I can get day easily with date.day and so on and I don't need to calculate anymore.
So I wonder is there any api or simple way to achieve it without any calculate.
I wonder better solution.
I don't think this functionality is built into Dart but you can somewhat easy add the following extension to Duration which are more or less what you are already are doing:
extension RestTimeOnDuration on Duration {
int get inDaysRest => inDays;
int get inHoursRest => inHours - (inDays * 24);
int get inMinutesRest => inMinutes - (inHours * 60);
int get inSecondsRest => inSeconds - (inMinutes * 60);
int get inMillisecondsRest => inMilliseconds - (inSeconds * 1000);
int get inMicrosecondsRest => inMicroseconds - (inMilliseconds * 1000);
}
void main() {
const duration = Duration(seconds: 123);
print('Days: ${duration.inDaysRest}'); // 0
print('Hours: ${duration.inHoursRest}'); // 0
print('Minutes: ${duration.inMinutesRest}'); // 2
print('Seconds: ${duration.inSecondsRest}'); // 3
print('Milliseconds: ${duration.inMillisecondsRest}'); // 0
print('Microseconds: ${duration.inMicrosecondsRest}'); // 0
}
Just use Duration(seconds: seconds), it handles values more than 60.
Duration(seconds: 123) // 2 minutes and 3 seconds

calculate hours/minutes between two times in dart

I want to get/calculate hours and minutes between two times in dart.
Example: if start_time is 17:30 and end_time is 09:00 (day after) it should return total: 15 hours 30 minutes
My code:
check_two_times_is_before(String start_time, String end_time){
var format = DateFormat("HH:mm");
var start = format.parse(start_time);
var end = format.parse(end_time);
if(start.isAfter(end)) {
// do something here
}
}
You can use difference method on DateTime class.
check_two_times_is_before(String start_time, String end_time){
var format = DateFormat("HH:mm");
var start = format.parse(start_time);
var end = format.parse(end_time);
if(start.isAfter(end)) {
end = end.add(Duration(days: 1));
Duration diff = end.difference(start);
final hours = diff.inHours;
final minutes = diff.inMinutes % 60;
print('$hours hours $minutes minutes');
}
}
You can try it with Duration class
Duration duration = end.difference(start).abs();
final hours = duration.inHours;
final minutes = duration.inMinutes % 60;
print('$hours hours $minutes minutes');
The question is pretty old but here is another solution which might help someone.
Duration duration = DateTime.fromMillisecondsSinceEpoch(timestmap).difference(DateTime.now()).abs();
final days = duration.inDays;
final hours = duration.inHours - (days * 24);
final minutes = duration.inMinutes - (days * 24 * 60) - (hours * 60);
final seconds = duration.inSeconds - (days * 24 * 60 * 60) - (hours * 60 * 60) - (minutes * 60);
Nothing to explain here really. We're just using basic algebra. We're getting the total number of milliseconds between the two timestamps and working that down to days, hours, minutes and seconds.

Dates (Duration) in Google Sheets Script

I have a Google Sheet with three columns:
- Date and time (timestamp)
- Duration
- Description
I have an script that when I write something in 'Description', inserts in 'Date' the date and time at this moment, and the 'Duration':
function onEdit(e) {
if(e.source.getActiveSheet().getName() == "Sheet2" ) {
var col = e.source.getActiveCell().getColumn();
if(col == 3 ) {
// I'm in column three
var cellTimeStamp = e.range.offset(0,-2); // First column of the same row
var cellTimeDiff = e.range.offset(0,-1); // Second column of the same row
var cellTimePrev = e.range.offset(-1,-2); // First column of the previous row
var timeTimeStamp = new Date();
var iniTime = cellTimePrev.getValue().getTime();
var finTime = timeTimeStamp.getTime() ;
var timeDiff = String(finTime - iniTime) ;
cellTimeStamp.setValue(timeTimeStamp);
cellTimeDiff.setValue(timeDiff); // [***]
}
}
}
When this executes (as an event) in the column of 'Duration' there is NOT something in the format of 'HH:mm:ss'.
But if I remove the last line in this script and adds this formulae in the sheet:
=A3-A2 (in row 3)
=A4-A3 (in row 4)
...
then it works ok.
I'd like to know how to meet the same result but with a script.
Thanks in advance.
timeDiff is the result of finTime - iniTime which are both native date object values, which means we have milliseconds .
converting that in hh:mm:ss is simple math... : 60 seconds in a minute and 60 minutes in an hour...
A simple code could be like this :
function msToTime(s) {
var ms = s % 1000;
s = (s - ms) / 1000;
var secs = s % 60;
s = (s - secs) / 60;
var mins = s % 60;
var hrs = (s - mins) / 60;
return hrs + ':' + mins + ':' + secs; // milliSecs are not shown but you can use ms if needed
}
If you prefer formating your string more conventionally (2 digits for each value) don't forget you can use Utilities.formatString() to do so.
example below :
return Utilities.formatString("%02d",hrs) + ':' + Utilities.formatString("%02d",mins) + ':' + Utilities.formatString("%02d",secs);
EDIT
Following your comment :
Spreadsheets are smarter than you think, you can try the code below and you will see that the result is actually a time value.(check by double clicking on it)
function test() {
var sh = SpreadsheetApp.getActiveSheet();
var t1 = sh.getRange('a1').getValue().getTime();
var t2 = sh.getRange('b1').getValue().getTime();
sh.getRange('c1').setValue(msToTime(t1-t2)).setNumberFormat('hh:mm:ss');
}
function msToTime(s) {
var ms = s % 1000;
s = (s - ms) / 1000;
var secs = s % 60;
s = (s - secs) / 60;
var mins = s % 60;
var hrs = (s - mins) / 60;
return hrs + ':' + mins + ':' + secs; // milliSecs are not shown but you can use ms if needed
}
note that setNumberFormat('hh:mm:ss') is optional, it's only there to force the spreadsheet to display hour:min:sec format but automatic mode works as well.

AVAudioPlayer currentTime exceeds duration

I'm making my own audio player using AVAudioPlayer.
NOTE: "p" is my instance of the player
Here's how I'm reading the track progress in one of the labels:
currentTime.text = [NSString stringWithFormat:#"%d:%02d", (int)p.currentTime / 60, (int)p.currentTime % 60];
Here's how I set the total duration of the track in one of the labels:
int seconds = (int)p.duration % 60;
int minutes = (int)p.duration / 60;
duration.text = [NSString stringWithFormat:#"%d:%02d", minutes, seconds];
When I run the app on the device, the track's current time ALWAYS exceeds the duration (by about 5-10 seconds).
Is this a bug in AVAudioPlayer, or am I not doing it correctly?
NOTE: This behavior also occurs on the device (not just on the simulator)
After finding the seconds by using % 60, you should remove those seconds when converting the remaining for the minutes. For e.g., with the total duration of 119 seconds after finding 59 seconds you should remove that from 119 and then do minute conversion for 60 seconds (119-59). That might solve your problem.
Minutes should be float: 152 seconds / 60.0f = 2.5333 not 2.
That being said, if you want to show the remaining minutes without the seconds you already obtain: int minutes = (p.duration-seconds) / 60
Also, for a better method to format time the way you want to, have a look at the second answer in this question (not the accepted solution).
Here is the function:
func setTimeString(duration: Double)->String {
var audioDurationSeconds = duration
var expression = ""
var minutesString = "00"
var minutesFloat = 0.0
if (audioDurationSeconds)/60 >= 1 {
minutesFloat = (audioDurationSeconds) / 60
audioDurationSeconds = TimeInterval(Int(audioDurationSeconds)%60)
if minutesFloat < 10.0 {
minutesString = String.init(format: "0%.f", floor(minutesFloat))
} else {
minutesString = String.init(format: "%.f", floor(minutesFloat))
}
}
if audioDurationSeconds < 10.0 {
expression = String.init(format: "%#:0%i", minutesString, Int(audioDurationSeconds))
} else {
expression = String.init(format: "%#:%i", minutesString, (Int(audioDurationSeconds)))
}
return expression
}
extension UILabel{
func getTimeString(from duration:Double) -> String{
let hours = Int(duration / 3600)
let minutes = Int(duration / 60) % 60
let seconds = Int(duration.truncatingRemainder(dividingBy: 60))
if hours > 0 {
return String(format: "%i:%02i:%02i", arguments: [hours,minutes,seconds])
}else {
return String(format: "%02i:%02i", arguments: [minutes,seconds])
}
}

iOS Game Center submit time elapsed

I'm trying to submit a double with the time that the user took to beat a stage. The leaderboard score format type is "Elapsed time - To the hundredth of a second". Something like this:
0:11:44.09
So I have a double that says the time is 11.734929 (it's 0:11:73). I multiply it to 6000 to convert it to int64_t. The result is 70409.572494. I can only send and int64_t so I'm losing 0.572494 seconds. The time sent is finally 0:11:44.09.
How can I send the full time instead of part of it?
EDIT:
I found the solution:
double my_time = ...
double intPart = 0;
double fractPart = modf(my_time, &intPart);
int isecs = (int)intPart;
int min = isecs / 60;
int sec = isecs % 60;
int hund = (int) (fractPart * 100);
int64_t time_to_send_through_game_center = min*6000 + (sec*100 + hund);
Not sure if this is what you are asking.
If you want 70409572.494 to be able to send 70409572, then multiply by 6000000 instead of 6000. This will convert 11.734929 to 70409572.494