0

Lets say I have start of and duration of a TV program with this format: 10:05.
What I want to do is when someone is entering programs data and he enters start time and duration of a program, my code will add them together and fill the next program's start time automatically.

I was trying to convert these times to seconds and then after manipulation convert them to formatted time again, but I don't know how can I do that.

function processTime(time) {    
    if (typeof time !== 'undefined') {
        var times = time.split(":");
        var minutes = times[0];
        var seconds = times[1];
        seconds = parseInt(seconds, 10) + (parseInt(minutes, 10) * 60);
    } else {
        var seconds = null;
    }
    return seconds;
}

function createTime(timestamp) {
    var output;
    if (typeof timestamp !== 'undefined') {
        // Problem is here, my timestamp is not standard unix timestamp
        var time = new Date(timestamp * 1000);
        var minutes = time.getMinutes();
        var seconds = time.getSeconds();
        output = minutes + ":" + seconds;
    }
    return output;
}

$progForm.delegate(".program-duration", 'keyup', function() {
        $(this).on('focusout', function() {
            var duration = processTime($(this).val());
            var startTime = processTime($(this).parent().prev().find(".program-time").val());
            if (duration && typeof duration !== 'undefined' && startTime && typeof startTime !== 'undefined') {
                var nextStart = duration + startTime;
                var $nextProgramTime = $(this).parent().parent().next().find(".program-time");
                if (parseInt($nextProgramTime.val()) < 1) {
                    $nextProgramTime.val(createTime(nextStart));
                }
            }
        });
    });


<form>
    <table>
        <tbody class="programs-inputs">
            <tr>
                <td><input type="text" class="program-time timepicker input-mini" name="programs[time][]" placeholder="00:00" /></td>
                <td><input type="text" class="program-duration timepicker input-mini" name="programs[duration][]" placeholder="00:00" /></td>
            </tr>
            <tr>
                <td><input type="text" class="program-time timepicker input-mini" name="programs[time][]" placeholder="00:00" /></td>
                <td><input type="text" class="program-duration timepicker input-mini" name="programs[duration][]" placeholder="00:00" /></td>
            </tr>
        </tbody>
    </table>
</form>
Farid Rn
  • 3,167
  • 5
  • 39
  • 66
  • Can you show what you have tried? – Niet the Dark Absol Apr 22 '13 at 21:47
  • @Kolink Here you are. – Farid Rn Apr 22 '13 at 21:52
  • Do you have a date (not only a time) as well? – Bergi Apr 22 '13 at 21:52
  • 1
    I think if you just have a duration you could instantiate a date with 0 for the values you don't need: var d = new Date(0, 0, 0, hours, minutes, seconds, milliseconds); – Andrew Walters Apr 22 '13 at 21:54
  • I don't see why your current solution would not work (apart from the missing leading zeros, and unless you are living in a timezone that has an half-our-offset). What is the problem you're talking of? Please provide same sample input and expected output. – Bergi Apr 22 '13 at 22:04
  • @Bergi my solution doesn't work because the timestamp that I'm creating is `610000` for `10:10` which is not a valid timestamp and the variables extracted from `Date` object won't be accurate. – Farid Rn Apr 22 '13 at 22:12
  • Not accurate? I correctly get `10` from `new Date(610e3).getMinutes()` and `new Date(610e3).getSeconds()`. It might be not the timestamp you actually wanted, but 610000 milliseconds after Jan 01 1970 00:00:00 is a *valid* timestamp for me. – Bergi Apr 22 '13 at 22:18
  • @Bergi `610` means `10:10` in seconds, right? but `new Date(610 * 1000).getMinutes();` will output `40`. – Farid Rn Apr 22 '13 at 22:29
  • 1
    What I've told you: you are living in a timezone that is some-and-a-half hours away from UTC! Use `getUTCMinutes()` to fix that bug :-) – Bergi Apr 22 '13 at 22:32
  • @Bergi thanks, I used Andrew Walters' solution to create valid js timestamps for now. – Farid Rn Apr 22 '13 at 22:40
  • 1
    @faridv: Notice that they're offset with your local timezone as well - beware of exchanging them with the server. You'd better be using `Date.UTC(0, 0, 0, hours, minutes, seconds, milliseconds);` – Bergi Apr 22 '13 at 22:43

2 Answers2

1

A unix timestamp shows the time since new years 1970. Since you are only interested in time, not date, unix timestamps is probably not suitable. You can just do the reverse of what you did before.

var seconds = totalSeconds;
var hours = Math.floor(seconds / 3600);
seconds -= hours * 3600;
var minutes = Math.floor(seconds / 60);
seconds -= minutes * 60;

var timeString = leadingZero(hours) + ':' + leadingZero(minutes) + ':' + leadingZero(seconds);

This does not give you the leading zeroes, but that should be fairly easy to fix.

function leadingZero(num) {
    var str = '';
    if (num < 10) {
        str += '0';
    }
    return str + num;
}
Reason
  • 1,410
  • 12
  • 33
  • Do you know how can I add leading zeros for numbers smaller than 10? – Farid Rn Apr 22 '13 at 22:01
  • 1
    updated the answer to feature the leading zeroes. not very pretty, but it solves the problem :). – Reason Apr 22 '13 at 22:06
  • thanks, I thought maybe there's a function in javascript to change to formatting of numbers like this. – Farid Rn Apr 22 '13 at 22:06
  • 1
    don't think there is a standard way. there are some other questions, like this one: http://stackoverflow.com/questions/1267283/how-can-i-create-a-zerofilled-value-using-javascript trying to solve the same problem. – Reason Apr 22 '13 at 22:08
1

Just use the inverse of your processTime algorithm:

function createTime(timestamp) {
    if (typeof timestamp == 'number') {
        var seconds = timestamp % 60;
        var minutes = (timestamp - seconds) / 60;
       return ("0"+minutes).slice(-2) + ":" + ("0"+seconds).slice(-2);
    }
}

Your original attempt was on the right way, only it was not timezone-proof. While new Date(timestamp * 1000); constructs a value for milliseconds from Jan 01 1970 00:00:00 UTC, the getMinutes() and getSeconds() methods will return the values for that timestamp in your current, local timezone - which can be half an hour off. Switch to their UTC equivalents (.getUTCMinutes(), .getUTCSeconds()) and it will work. Using the solution with Date objects will save you much trouble once you need to include hours, or maybe even full dates :-)

Bergi
  • 630,263
  • 148
  • 957
  • 1,375