Am I dividing the time of day correctly in MS Access? - ms-access

I have a field that has a bunch of shifts where SH1 is from 6am-2pm, SH2 is from 2pm-10pm, and SH3 is from 10pm-6am. I need to only return the current shift, based on the current time.
What I've tried:
Switch(
[Uf_Shift_Standard]=8,
(Switch(
(Time() >= #6 am# AND Time() < #2 pm#), "SH1",
(Time() >= #2 pm# AND Time() < #10 pm#), "SH2",
True, "SH3")
),
[Uf_Shift_Standard]=10,
(Switch(
(Time() >= #5 am# AND Time() < #3 pm#), "SH1",
True, "SH2")),
[Uf_Shift_Standard]=12,
(Switch(
(Time() >= #3 am# AND Time() < #3 pm#), "SH1",
True, "SH2")),
1=1,
(Switch(
(Time() >= #6 am# AND Time() < #2 pm#), "SH1",
(Time() >= #2 pm# AND Time() < #10 pm#), "SH2",
True, "SH3"))
)
Note: I've updated my code to account for the 3 different types of shift lengths we have - an 8, 10, and 12 hour shift. However, I'm not getting the error: You tried to execute a query that does not include the specified expression 'tableA.job="something" And tableB.suffix="12" And tableB.shift=Switch([Uf_Shift_Standard]=8,Switch...[the rest of the long expression continues here...]
The 'tableA.job="something" And tableB.suffix="12" part deals with 2 other columns before the shift column that have criteria of their own.

It can be done with a one-liner:
Shift = "SH" & 1 + DatePart("h", DateAdd("h", -6, Time())) \ 8
In the GUI designer:
Shift: "SH" & 1+DatePart("h",DateAdd("h",-6,Time()))\8

Related

SSRS tweak to time expression

I am currently using this expression to show the previous working day in an SSRS report:
=DateAdd("d"
, Switch(DatePart("w", Today) = 2, -3
,DatePart("w", Today) = 1, -2
,True, -1)
, Today)
which works fine.
However I would like the output to be,if I ran the query today for example,:
24/04/2020 23:59:59
Instead of the current 24/04/2020
Please can you advise on how I could add hours, minutes and seconds- 23:59:59 - to the above expression?
Thank you
There may be a more elegant way of doing this but I based this on you current expression. I've text it and it seems to work OK.
=DateAdd("s"
, Switch(
DatePart("w", Today) = 2, (-3 * 86400) -1,
DatePart("w", Today) = 1, (-2 * 86400) -1,
True, -85401
)
, Today)
This simply does a datediff in seconds rather than days and then adjusts the amount of seconds to remove by 1

How to convert a simple timer into hour minute and second format in angular 7 [duplicate]

How can I convert seconds to an HH-MM-SS string using JavaScript?
You can manage to do this without any external JavaScript library with the help of JavaScript Date method like following:
const date = new Date(null);
date.setSeconds(SECONDS); // specify value for SECONDS here
const result = date.toISOString().slice(11, 19);
Or, as per #Frank's comment; a one liner:
new Date(SECONDS * 1000).toISOString().slice(11, 19);
Updated (2020):
Please use #Frank's one line solution:
new Date(SECONDS * 1000).toISOString().substring(11, 16)
If SECONDS<3600 and if you want to show only MM:SS then use below code:
new Date(SECONDS * 1000).toISOString().substring(14, 19)
It is by far the best solution.
Old answer:
Use the Moment.js library.
I don't think any built-in feature of the standard Date object will do this for you in a way that's more convenient than just doing the math yourself.
hours = Math.floor(totalSeconds / 3600);
totalSeconds %= 3600;
minutes = Math.floor(totalSeconds / 60);
seconds = totalSeconds % 60;
Example:
let totalSeconds = 28565;
let hours = Math.floor(totalSeconds / 3600);
totalSeconds %= 3600;
let minutes = Math.floor(totalSeconds / 60);
let seconds = totalSeconds % 60;
console.log("hours: " + hours);
console.log("minutes: " + minutes);
console.log("seconds: " + seconds);
// If you want strings with leading zeroes:
minutes = String(minutes).padStart(2, "0");
hours = String(hours).padStart(2, "0");
seconds = String(seconds).padStart(2, "0");
console.log(hours + ":" + minutes + ":" + seconds);
I know this is kinda old, but...
ES2015:
var toHHMMSS = (secs) => {
var sec_num = parseInt(secs, 10)
var hours = Math.floor(sec_num / 3600)
var minutes = Math.floor(sec_num / 60) % 60
var seconds = sec_num % 60
return [hours,minutes,seconds]
.map(v => v < 10 ? "0" + v : v)
.filter((v,i) => v !== "00" || i > 0)
.join(":")
}
It will output:
toHHMMSS(129600) // 36:00:00
toHHMMSS(13545) // 03:45:45
toHHMMSS(180) // 03:00
toHHMMSS(18) // 00:18
As Cleiton pointed out in his answer, moment.js can be used for this:
moment().startOf('day')
.seconds(15457)
.format('H:mm:ss');
Here's a simple function for converting times that might help
function formatSeconds(seconds) {
var date = new Date(1970,0,1);
date.setSeconds(seconds);
return date.toTimeString().replace(/.*(\d{2}:\d{2}:\d{2}).*/, "$1");
}
This does the trick:
function secondstotime(secs)
{
var t = new Date(1970,0,1);
t.setSeconds(secs);
var s = t.toTimeString().substr(0,8);
if(secs > 86399)
s = Math.floor((t - Date.parse("1/1/70")) / 3600000) + s.substr(2);
return s;
}
(Sourced from here)
var timeInSec = "661"; //even it can be string
String.prototype.toHHMMSS = function () {
/* extend the String by using prototypical inheritance */
var seconds = parseInt(this, 10); // don't forget the second param
var hours = Math.floor(seconds / 3600);
var minutes = Math.floor((seconds - (hours * 3600)) / 60);
seconds = seconds - (hours * 3600) - (minutes * 60);
if (hours < 10) {hours = "0"+hours;}
if (minutes < 10) {minutes = "0"+minutes;}
if (seconds < 10) {seconds = "0"+seconds;}
var time = hours+':'+minutes+':'+seconds;
return time;
}
alert("5678".toHHMMSS()); // "01:34:38"
console.log(timeInSec.toHHMMSS()); //"00:11:01"
we can make this function lot shorter and crisp but that decreases the readability, so we will write it as simple as possible and as stable as possible.
or you can check this working here:
Try this:
function toTimeString(seconds) {
return (new Date(seconds * 1000)).toUTCString().match(/(\d\d:\d\d:\d\d)/)[0];
}
I think the most general (and cryptic) solution could be this
function hms(seconds) {
return [3600, 60]
.reduceRight(
(pipeline, breakpoint) => remainder =>
[Math.floor(remainder / breakpoint)].concat(pipeline(remainder % breakpoint)),
r => [r]
)(seconds)
.map(amount => amount.toString().padStart(2, '0'))
.join('-');
}
Or to copy & paste the shortest version
function hms(seconds) {
return [3600, 60]
.reduceRight(
(p, b) => r => [Math.floor(r / b)].concat(p(r % b)),
r => [r]
)(seconds)
.map(a => a.toString().padStart(2, '0'))
.join('-');
}
Some example outputs:
> hms(0)
< "00-00-00"
> hms(5)
< "00-00-05"
> hms(60)
< "00-01-00"
> hms(3785)
< "01-03-05"
> hms(37850)
< "10-30-50"
> hms(378500)
< "105-08-20"
How it works
Algorithm
To get hours you divide total seconds by 3600 and floor it.
To get minutes you divide remainder by 60 and floor it.
To get seconds you just use the remainder.
It would also be nice to keep individual amounts in an array for easier formatting.
For example given the input of 3785s the output should be [1, 3, 5], that is 1 hour, 3 minutes and 5 seconds.
Creating pipeline
Naming the 3600 and 60 constants "breakpoints" you can write this algorithm into function as this
function divideAndAppend(remainder, breakpoint, callback) {
return [Math.floor(remainder / breakpoint)].concat(callback(remainder % breakpoint));
}
It returns an array where first item is the amount for given breakpoint and the rest of the array is given by the callback.
Reusing the divideAndAppend in callback function will give you a pipeline of composed divideAndAppend functions. Each one of these
computes amount per given breakpoint and append it to the array making your desired output.
Then you also need the "final" callback that ends this pipeline. In another words you used all breakpoints and now you have only the remainder.
Since you have already the answer at 3) you should use some sort of identity function, in this case remainder => [remainder].
You can now write the pipeline like this
let pipeline = r3 => divideAndAppend(
r3,
3600,
r2 => divideAndAppend(
r2,
60,
r1 => [r1]));
> pipeline(3785)
< [1, 3, 5]
Cool right?
Generalizing using for-loop
Now you can generalize with a variable amount of breakpoints and create a for-loop that will compose individial divideAndAppend functions into
the pipeline.
You start with the identity function r1 => [r1], then use the 60 breakpoint and finally use the 3600 breakpoint.
let breakpoints = [60, 3600];
let pipeline = r => [r];
for (const b of breakpoints) {
const previousPipeline = pipeline;
pipeline = r => divideAndAppend(r, b, previousPipeline);
}
> pipeline(3785)
< [1, 3, 5]
Using Array.prototype.reduce()
Now you can rewrite this for-loop into reducer for shorter and more functional code. In other words rewrite function composition into the reducer.
let pipeline = [60, 3600].reduce(
(ppln, b) => r => divideAndAppend(r, b, ppln),
r => [r]
);
> pipeline(3785)
< [1, 3, 5]
The accumulator ppln is the pipeline and you are composing it using the previous version of it. The initial pipeline is r => [r].
You can now inline the function divideAndAppend and use Array.prototype.reduceRight which is the same as [].reverse().reduce(...) to make the breakpoints
definitions more natural.
let pipeline = [3600, 60]
.reduceRight(
(ppln, b) => r => [Math.floor(r / b)].concat(ppln(r % b)),
r => [r]
);
Which is the final form. Then you just appy mapping to string with padded 0's on left and join the strings with : separator;
More generalizations
Wrapping the reducer into function
function decompose(total, breakpoints) {
return breakpoints.reduceRight(
(p, b) => r => [Math.floor(r / b)].concat(p(r % b)),
r => [r]
)(total);
}
> decompose(3785, [3600, 60])
< [1, 3, 5]
you now have very general algorithm you can work with. For example:
Convert easily (the weird) us length standards
Given the standards
Unit
Divisions
1 foot
12 inches
1 yard
3 feet
1 mile
1760 yards
> decompose(123_456, [1760 * 3 * 12, 3 * 12, 12])
< [1, 1669, 1, 0]
123456 in = 1 mi, 1669 yd, 1 feet and 0 in
Or you can somewhat convert to decimal or binary representations
> decompose(123_456, [100_000, 10_000, 1000, 100, 10])
< [1, 2, 3, 4, 5, 6]
> decompose(127, [128, 64, 32, 16, 8, 4, 2])
< [0, 1, 1, 1, 1, 1, 1, 1]
Works also with floating point breakpoints
Since Javascript supports mod operator with floating point numbers, you can also do
> decompose(26.5, [20, 2.5])
< [1, 2, 1.5]
The edge case of no breakpoints is also naturally covered
> decompose(123, [])
< [123]
Here is an extension to Number class. toHHMMSS() converts seconds to an hh:mm:ss string.
Number.prototype.toHHMMSS = function() {
var hours = Math.floor(this / 3600) < 10 ? ("00" + Math.floor(this / 3600)).slice(-2) : Math.floor(this / 3600);
var minutes = ("00" + Math.floor((this % 3600) / 60)).slice(-2);
var seconds = ("00" + (this % 3600) % 60).slice(-2);
return hours + ":" + minutes + ":" + seconds;
}
// Usage: [number variable].toHHMMSS();
// Here is a simple test
var totalseconds = 1234;
document.getElementById("timespan").innerHTML = totalseconds.toHHMMSS();
// HTML of the test
<div id="timespan"></div>
Easy to follow version for noobies:
var totalNumberOfSeconds = YOURNUMBEROFSECONDS;
var hours = parseInt( totalNumberOfSeconds / 3600 );
var minutes = parseInt( (totalNumberOfSeconds - (hours * 3600)) / 60 );
var seconds = Math.floor((totalNumberOfSeconds - ((hours * 3600) + (minutes * 60))));
var result = (hours < 10 ? "0" + hours : hours) + ":" + (minutes < 10 ? "0" + minutes : minutes) + ":" + (seconds < 10 ? "0" + seconds : seconds);
console.log(result);
This function should do it :
var convertTime = function (input, separator) {
var pad = function(input) {return input < 10 ? "0" + input : input;};
return [
pad(Math.floor(input / 3600)),
pad(Math.floor(input % 3600 / 60)),
pad(Math.floor(input % 60)),
].join(typeof separator !== 'undefined' ? separator : ':' );
}
Without passing a separator, it uses : as the (default) separator :
time = convertTime(13551.9941351); // --> OUTPUT = 03:45:51
If you want to use - as a separator, just pass it as the second parameter:
time = convertTime(1126.5135155, '-'); // --> OUTPUT = 00-18-46
See also this Fiddle.
Chiming in on this old thread -- the OP stated HH:MM:SS, and many of the solutions work, until you realize you need more than 24 hours listed. And maybe you don't want more than a single line of code. Here you go:
d=(s)=>{f=Math.floor;g=(n)=>('00'+n).slice(-2);return f(s/3600)+':'+g(f(s/60)%60)+':'+g(s%60)}
It returns H+:MM:SS. To use it, simply use:
d(91260); // returns "25:21:00"
d(960); // returns "0:16:00"
...I tried to get it to use the least amount of code possible, for a nice one-liner approach.
For the special case of HH:MM:SS.MS (eq: "00:04:33.637") as used by FFMPEG to specify milliseconds.
[-][HH:]MM:SS[.m...]
HH expresses the number of hours, MM the number of minutes for a
maximum of 2 digits, and SS the number of seconds for a maximum of 2
digits. The m at the end expresses decimal value for SS.
/* HH:MM:SS.MS to (FLOAT)seconds ---------------*/
function timerToSec(timer){
let vtimer = timer.split(":")
let vhours = +vtimer[0]
let vminutes = +vtimer[1]
let vseconds = parseFloat(vtimer[2])
return vhours * 3600 + vminutes * 60 + vseconds
}
/* Seconds to (STRING)HH:MM:SS.MS --------------*/
function secToTimer(sec){
let o = new Date(0)
let p = new Date(sec*1000)
return new Date(p.getTime()-o.getTime())
.toISOString()
.split("T")[1]
.split("Z")[0]
}
/* Example: 7hours, 4 minutes, 33 seconds and 637 milliseconds */
const t = "07:04:33.637"
console.log(
t + " => " +
timerToSec(t) +
"s"
)
/* Test: 25473 seconds and 637 milliseconds */
const s = 25473.637 // "25473.637"
console.log(
s + "s => " +
secToTimer(s)
)
Example usage, a milliseconds transport timer:
/* Seconds to (STRING)HH:MM:SS.MS --------------*/
function secToTimer(sec){
let o = new Date(0)
let p = new Date(sec*1000)
return new Date(p.getTime()-o.getTime())
.toISOString()
.split("T")[1]
.split("Z")[0]
}
let job, origin = new Date().getTime()
const timer = () => {
job = requestAnimationFrame(timer)
OUT.textContent = secToTimer((new Date().getTime() - origin) / 1000)
}
requestAnimationFrame(timer)
span {font-size:4rem}
<span id="OUT"></span>
<br>
<button onclick="origin = new Date().getTime()">RESET</button>
<button onclick="requestAnimationFrame(timer)">RESTART</button>
<button onclick="cancelAnimationFrame(job)">STOP</button>
Example usage, binded to a media element
/* Seconds to (STRING)HH:MM:SS.MS --------------*/
function secToTimer(sec){
let o = new Date(0)
let p = new Date(sec*1000)
return new Date(p.getTime()-o.getTime())
.toISOString()
.split("T")[1]
.split("Z")[0]
}
VIDEO.addEventListener("timeupdate", function(e){
OUT.textContent = secToTimer(e.target.currentTime)
}, false)
span {font-size:4rem}
<span id="OUT"></span><br>
<video id="VIDEO" width="400" controls autoplay>
<source src="https://www.w3schools.com/html/mov_bbb.mp4" type="video/mp4">
</video>
Outside the question, those functions written in php:
<?php
/* HH:MM:SS to (FLOAT)seconds ------------------*/
function timerToSec($timer){
$vtimer = explode(":",$timer);
$vhours = (int)$vtimer[0];
$vminutes = (int)$vtimer[1];
$vseconds = (float)$vtimer[2];
return $vhours * 3600 + $vminutes * 60 + $vseconds;
}
/* Seconds to (STRING)HH:MM:SS -----------------*/
function secToTimer($sec){
return explode(" ", date("H:i:s", $sec))[0];
}
After looking at all the answers and not being happy with most of them, this is what I came up with. I know I am very late to the conversation, but here it is anyway.
function secsToTime(secs){
var time = new Date();
// create Date object and set to today's date and time
time.setHours(parseInt(secs/3600) % 24);
time.setMinutes(parseInt(secs/60) % 60);
time.setSeconds(parseInt(secs%60));
time = time.toTimeString().split(" ")[0];
// time.toString() = "HH:mm:ss GMT-0800 (PST)"
// time.toString().split(" ") = ["HH:mm:ss", "GMT-0800", "(PST)"]
// time.toTimeString().split(" ")[0]; = "HH:mm:ss"
return time;
}
I create a new Date object, change the time to my parameters, convert the Date Object to a time string, and removed the additional stuff by splitting the string and returning only the part that need.
I thought I would share this approach, since it removes the need for regex, logic and math acrobatics to get the results in "HH:mm:ss" format, and instead it relies on built in methods.
You may want to take a look at the documentation here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date
below is the given code which will convert seconds into hh-mm-ss format:
var measuredTime = new Date(null);
measuredTime.setSeconds(4995); // specify value of SECONDS
var MHSTime = measuredTime.toISOString().substr(11, 8);
Get alternative method from Convert seconds to HH-MM-SS format in JavaScript
var time1 = date1.getTime();
var time2 = date2.getTime();
var totalMilisec = time2 - time1;
alert(DateFormat('hh:mm:ss',new Date(totalMilisec)))
/* ----------------------------------------------------------
* Field | Full Form | Short Form
* -------------|--------------------|-----------------------
* Year | yyyy (4 digits) | yy (2 digits)
* Month | MMM (abbr.) | MM (2 digits)
| NNN (name) |
* Day of Month | dd (2 digits) |
* Day of Week | EE (name) | E (abbr)
* Hour (1-12) | hh (2 digits) |
* Minute | mm (2 digits) |
* Second | ss (2 digits) |
* ----------------------------------------------------------
*/
function DateFormat(formatString,date){
if (typeof date=='undefined'){
var DateToFormat=new Date();
}
else{
var DateToFormat=date;
}
var DAY = DateToFormat.getDate();
var DAYidx = DateToFormat.getDay();
var MONTH = DateToFormat.getMonth()+1;
var MONTHidx = DateToFormat.getMonth();
var YEAR = DateToFormat.getYear();
var FULL_YEAR = DateToFormat.getFullYear();
var HOUR = DateToFormat.getHours();
var MINUTES = DateToFormat.getMinutes();
var SECONDS = DateToFormat.getSeconds();
var arrMonths = new Array("January","February","March","April","May","June","July","August","September","October","November","December");
var arrDay=new Array('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday');
var strMONTH;
var strDAY;
var strHOUR;
var strMINUTES;
var strSECONDS;
var Separator;
if(parseInt(MONTH)< 10 && MONTH.toString().length < 2)
strMONTH = "0" + MONTH;
else
strMONTH=MONTH;
if(parseInt(DAY)< 10 && DAY.toString().length < 2)
strDAY = "0" + DAY;
else
strDAY=DAY;
if(parseInt(HOUR)< 10 && HOUR.toString().length < 2)
strHOUR = "0" + HOUR;
else
strHOUR=HOUR;
if(parseInt(MINUTES)< 10 && MINUTES.toString().length < 2)
strMINUTES = "0" + MINUTES;
else
strMINUTES=MINUTES;
if(parseInt(SECONDS)< 10 && SECONDS.toString().length < 2)
strSECONDS = "0" + SECONDS;
else
strSECONDS=SECONDS;
switch (formatString){
case "hh:mm:ss":
return strHOUR + ':' + strMINUTES + ':' + strSECONDS;
break;
//More cases to meet your requirements.
}
}
I just wanted to give a little explanation to the nice answer above:
var totalSec = new Date().getTime() / 1000;
var hours = parseInt( totalSec / 3600 ) % 24;
var minutes = parseInt( totalSec / 60 ) % 60;
var seconds = totalSec % 60;
var result = (hours < 10 ? "0" + hours : hours) + "-" + (minutes < 10 ? "0" + minutes : minutes) + "-" + (seconds < 10 ? "0" + seconds : seconds);
On the second line, since there are 3600 seconds in 1 hour, we divide the total number of seconds by 3600 to get the total number of hours. We use parseInt to strip off any decimal. If totalSec was 12600 (3 and half hours), then parseInt( totalSec / 3600 ) would return 3, since we will have 3 full hours. Why do we need the % 24 in this case? If we exceed 24 hours, let's say we have 25 hours (90000 seconds), then the modulo here will take us back to 1 again, rather than returning 25. It is confining the result within a 24 hour limit, since there are 24 hours in one day.
When you see something like this:
25 % 24
Think of it like this:
25 mod 24 or what is the remainder when we divide 25 by 24
None of the answers here satisfies my requirements as I want to be able to handle
Large numbers of seconds (days), and
Negative numbers
Although those are not required by the OP, it's good practice to cover edge cases, especially when it takes little effort.
It's pretty obvious is that the OP means a NUMBER of seconds when he says seconds. Why would peg your function on String?
function secondsToTimeSpan(seconds) {
const value = Math.abs(seconds);
const days = Math.floor(value / 1440);
const hours = Math.floor((value - (days * 1440)) / 3600);
const min = Math.floor((value - (days * 1440) - (hours * 3600)) / 60);
const sec = value - (days * 1440) - (hours * 3600) - (min * 60);
return `${seconds < 0 ? '-':''}${days > 0 ? days + '.':''}${hours < 10 ? '0' + hours:hours}:${min < 10 ? '0' + min:min}:${sec < 10 ? '0' + sec:sec}`
}
secondsToTimeSpan(0); // => 00:00:00
secondsToTimeSpan(1); // => 00:00:01
secondsToTimeSpan(1440); // => 1.00:00:00
secondsToTimeSpan(-1440); // => -1.00:00:00
secondsToTimeSpan(-1); // => -00:00:01
Simple function to convert seconds into in hh:mm:ss format :
function getHHMMSSFromSeconds(totalSeconds) {
if (!totalSeconds) {
return '00:00:00';
}
const hours = Math.floor(totalSeconds / 3600);
const minutes = Math.floor(totalSeconds % 3600 / 60);
const seconds = totalSeconds % 60;
const hhmmss = padTo2(hours) + ':' + padTo2(minutes) + ':' + padTo2(seconds);
return hhmmss;
}
// function to convert single digit to double digit
function padTo2(value) {
if (!value) {
return '00';
}
return value < 10 ? String(value).padStart(2, '0') : value;
}
Here is a function to convert seconds to hh-mm-ss format based on powtac's answer here
jsfiddle
/**
* Convert seconds to hh-mm-ss format.
* #param {number} totalSeconds - the total seconds to convert to hh- mm-ss
**/
var SecondsTohhmmss = function(totalSeconds) {
var hours = Math.floor(totalSeconds / 3600);
var minutes = Math.floor((totalSeconds - (hours * 3600)) / 60);
var seconds = totalSeconds - (hours * 3600) - (minutes * 60);
// round seconds
seconds = Math.round(seconds * 100) / 100
var result = (hours < 10 ? "0" + hours : hours);
result += "-" + (minutes < 10 ? "0" + minutes : minutes);
result += "-" + (seconds < 10 ? "0" + seconds : seconds);
return result;
}
Example use
var seconds = SecondsTohhmmss(70);
console.log(seconds);
// logs 00-01-10
There are lots of options of solve this problem, and obvious there are good option suggested about, But I wants to add one more optimized code here
function formatSeconds(sec) {
return [(sec / 3600), ((sec % 3600) / 60), ((sec % 3600) % 60)]
.map(v => v < 10 ? "0" + parseInt(v) : parseInt(v))
.filter((i, j) => i !== "00" || j > 0)
.join(":");
}
if you don't wants formatted zero with less then 10 number, you can use
function formatSeconds(sec) {
return parseInt(sec / 3600) + ':' + parseInt((sec % 3600) / 60) + ':' + parseInt((sec % 3600) % 60);
}
Sample Code http://fiddly.org/1c476/1
In one line, using T.J. Crowder's solution :
secToHHMMSS = seconds => `${Math.floor(seconds / 3600)}:${Math.floor((seconds % 3600) / 60)}:${Math.floor((seconds % 3600) % 60)}`
In one line, another solution that also count days :
secToDHHMMSS = seconds => `${parseInt(seconds / 86400)}d ${new Date(seconds * 1000).toISOString().substr(11, 8)}`
Source : https://gist.github.com/martinbean/2bf88c446be8048814cf02b2641ba276
var sec_to_hms = function(sec){
var min, hours;
sec = sec - (min = Math.floor(sec/60))*60;
min = min - (hours = Math.floor(min/60))*60;
return (hours?hours+':':'') + ((min+'').padStart(2, '0')) + ':'+ ((sec+'').padStart(2, '0'));
}
alert(sec_to_hms(2442542));
Have you tried adding seconds to a Date object?
Date.prototype.addSeconds = function(seconds) {
this.setSeconds(this.getSeconds() + seconds);
};
var dt = new Date();
dt.addSeconds(1234);
A sample:
https://jsfiddle.net/j5g2p0dc/5/
Updated:
Sample link was missing so I created a new one.
You can also use below code:
int ss = nDur%60;
nDur = nDur/60;
int mm = nDur%60;
int hh = nDur/60;
For anyone using AngularJS, a simple solution is to filter the value with the date API, which converts milliseconds to a string based on the requested format. Example:
<div>Offer ends in {{ timeRemaining | date: 'HH:mm:ss' }}</div>
Note that this expects milliseconds, so you may want to multiply timeRemaining by 1000 if you are converting from seconds (as the original question was formulated).
I ran into the case some have mentioned where the number of seconds is more than a day. Here's an adapted version of #Harish Anchu's top-rated answer that accounts for longer periods of time:
function secondsToTime(seconds) {
const arr = new Date(seconds * 1000).toISOString().substr(11, 8).split(':');
const days = Math.floor(seconds / 86400);
arr[0] = parseInt(arr[0], 10) + days * 24;
return arr.join(':');
}
Example:
secondsToTime(101596) // outputs '28:13:16' as opposed to '04:13:16'
String.prototype.toHHMMSS = function () {
var sec_num = parseInt(this, 10); // don't forget the second param
var hours = Math.floor(sec_num / 3600);
var minutes = Math.floor((sec_num - (hours * 3600)) / 60);
var seconds = sec_num - (hours * 3600) - (minutes * 60);
if (hours < 10) {hours = "0"+hours;}
if (minutes < 10) {minutes = "0"+minutes;}
if (seconds < 10) {seconds = "0"+seconds;}
return hours+':'+minutes+':'+seconds;
}
Usage Example
alert("186".toHHMMSS());

Datediff in MsAccess

I am stuck in one place.
I am using DateDiff in Ms Access it is giving me proper output, like
StartDate is 10-Sep-2016
EndDate is 15-Oct-2016
Total Days which I will get is 35
& months will i get is 1 Month
DateDiff('d',StartDate,EndDate)
**But I want output as 2 months if it is exeeded the 30 days.
if it is 61 days then 3 months & so on.
**IIFFF days diffrence is
29 Days then output should be 1 months
30 Days then output should be 1 months
32 Days then output should be 2 months
60 Days then output should be 2 months
62 Days then output should be 3 months**
Will that be possible in the DateDiff in MsAccess
or is there any other function available so that i can achieve the same output.**
You can do this using conditional logic. Perhaps something like this:
select iif(DateDiff('d', StartDate, EndDate) > 30,
DateDiff('d',StartDate,EndDate) & " days",
"2 months"
)
Your logic that anything exceeding 30 days is "2 months" seems strange. Normally, I think the logic would look like this:
select iif(DateDiff('d', StartDate, EndDate) > 30,
DateDiff('d', StartDate, EndDate) & " days",
DateDiff('m', StartDate, EndDate) & " months"
)
will this logic suffice to modify your SQL function?
Public Function FN_GET_MONTH(iDays As Long, Optional iDaysInMonth As Long = 30)
If (iDays / iDaysInMonth) > iDays \ iDaysInMonth Then
FN_GET_MONTH = (iDays \ iDaysInMonth) + 1
Else
FN_GET_MONTH = (iDays \ iDaysInMonth)
End If
End Function
?FN_GET_MONTH(29) = 1
?FN_GET_MONTH(31) = 2
?FN_GET_MONTH(60) = 2
?FN_GET_MONTH(80) = 3
?FN_GET_MONTH(91) = 4
you can have this public function and use it in your SQL code like
FN_GET_MONTH(DateDiff("d", StartDate, EndDate))
This query seems to give the results you seek:
SELECT
StartDate,
EndDate
numDays,
((numDays - 1) \ 30) + 1 AS numMonths
FROM
(
SELECT
StartDate,
EndDate,
DateDiff("d", StartDate, EndDate) AS numDays
FROM YourTable
)
It gives me
numDays numMonths
------- ---------
...
29 1
30 1
31 2
32 2
...
59 2
60 2
61 3
62 3
...
It seems like your minimum count of months for a positive count of days is 1, thus:
MonthCount = Sgn(DateDiff("d",StartDate,EndDate)) + DateDiff("m",StartDate,EndDate)
Edit
For a 30-day cut that will produce your example output, use this simple formula in your query:
MonthCount: (DateDiff("d",[StartDate],[EndDate])-1)\30+1

SSRS Expression First Day of of First Week of Current Year

Everyone,
I have a question that has stumped me for a day and can't figure out. What I am looking for is a formula in SSRS Expression that will tell me what the date is for the first day of the first ISO week of the current year.
For Example:
2014 would yield: 12/30/2013. The reason for this would be that the first ISO week of the 2014 year is from (12/30/2013) - (01/05/2014).
2013 would yield: 12/31/2012
I would appreciate any help anyone?
Thanks,
You can use this function:
Public Function dtFirstDayOfISOYear(ByVal intYear As Integer) as Datetime
'the first week of a ISO year is the week that contains the first Thursday of the year (and, hence, 4 January)
Dim intDayOfWeek As Integer = CInt(New DateTime(intYear, 1, 4).DayOfWeek)
'ISO weeks start with Monday
If intDayOfWeek < DayOfWeek.Monday Then intDayOfWeek = intDayOfWeek + 7
Return DateAdd(DateInterval.Day, -intDayOfWeek + 1, New DateTime(intYear, 1, 4))
End Function
And call it using an Expression like this:
=Code.dtFirstDayOfISOYear(2014)
You can also use a standalone Expression like this:
=DateAdd("d", (-1) * (CInt(New DateTime(2014, 1, 4).DayOfWeek) + IIf(CInt(New DateTime(2014, 1, 4).DayOfWeek) < DayOfWeek.Monday, 7, 0)) + 1, New DateTime(2014, 1, 4))

Code Golf: Calculate Orthodox Easter date

Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
The Challenge
Calculate the Date of the Greek Orthodox Easter (http://www.timeanddate.com/holidays/us/orthodox-easter-day) Sunday in a given Year (1900-2100) using the least amount of characters.
Input is just a year in the form '2010'. It's not relevant where you get it (Input, CommandLineArgs etc.) but it must be dynamic!
Output should be in the form day-month-year (say dd/mm/yyyy or d/m/yyyy)
Restrictions No standard functions, such as Mathematica's EasterSundayGreekOrthodox or PHP's easter_date(), which return the (not applicable gregorian) date automatic must be used!
Examples
2005 returns 1/5/2005
2006 returns 23/4/2006
2007 returns 8/4/2007
2008 returns 27/4/2008
2009 returns 19/4/2009
2010 returns 4/4/2010
2011 returns 24/4/2011
2012 returns 15/4/2012
2013 returns 5/5/2013
2014 returns 20/4/2014
2015 returns 12/4/2015
Code count includes input/output (i.e full program).
Edit:
I mean the Eastern Easter Date.
Reference: http://en.wikipedia.org/wiki/Computus
Python (101 140 132 115 chars)
y=input()
d=(y%19*19+15)%30
e=(y%4*2+y%7*4-d+34)%7+d+127
m=e/31
a=e%31+1+(m>4)
if a>30:a,m=1,5
print a,'/',m,'/',y
This one uses the Meeus Julian algorithm but since this one only works between 1900 and 2099, an implementation using Anonymous Gregorian algorithm is coming right up.
Edit: Now 2005 is properly handled. Thanks to Mark for pointing it out.
Edit 2: Better handling of some years, thanks for all the input!
Edit 3: Should work for all years in range. (Sorry for hijacking it Juan.)
PHP CLI, no easter_date(), 125 characters
Valid for dates from 13 March 1900 to 13 March 2100, now works for Easters that fall in May
Code:
<?=date("d/m/Y",mktime(0,0,0,floor(($b=($a=(19*(($y=$argv[1])%19)+15)%30)+(2*($y%4)+4*$y%7-$a+34)%7+114)/31),($b%31)+14,$y));
Invocation:
$ php codegolf.php 2010
$ php codegolf.php 2005
Output:
04/04/2010
01/05/2005
With whitespace:
<?=date("d/m/Y", mktime(0, 0, 0, floor(($b = ($a = (19 * (($y = $argv[1]) % 19) + 15) % 30) + (2 * ($y % 4) + 4 * $y % 7 - $a + 34) % 7 + 114) / 31), ($b % 31) + 14, $y));
This iteration is no longer readable thanks to PHP's handling of assignments. It's almost a functional language!
For completeness, here's the previous, 127 character solution that does not rely on short tags:
Code:
echo date("d/m/Y",mktime(0,0,0,floor(($b=($a=(19*(($y=$argv[1])%19)+15)%30)+(2*($y%4)+4*$y%7-$a+34)%7+114)/31),($b%31)+14,$y));
Invocation:
$ php -r 'echo date("d/m/Y",mktime(0,0,0,floor(($b=($a=(19*(($y=$argv[1])%19)+15)%30)+(2*($y%4)+4*$y%7-$a+34)%7+114)/31),($b%31)+14,$y));' 2010
$ php -r 'echo date("d/m/Y",mktime(0,0,0,floor(($b=($a=(19*(($y=$argv[1])%19)+15)%30)+(2*($y%4)+4*$y%7-$a+34)%7+114)/31),($b%31)+14,$y));' 2005
C#, 155 157 182 209 212 characters
class P{static void Main(string[]i){int y=int.Parse(i[0]),c=(y%19*19+15)%30,d=c+(y%4*2+y%7*4-c+34)%7+128;System.Console.Write(d%31+d/155+"/"+d/31+"/"+y);}}
Python 2.3, 97 characters
y=int(input())
c=(y%19*19+15)%30
d=c+(y%4*2+y%7*4-c+34)%7+128
print"%d/%d/%d"%(d%31+d/155,d/31,y)
This also uses the Meeus Julian algorithm (and should work for dates in May).
removed no longer necessary check for modern years and zero-padding in output
don't expect Easters in March anymore because there are none between 1800-2100
included Python 2.3 version (shortest so far)
Mathematica
<<Calendar`;a=Print[#3,"/",#2,"/",#]&##EasterSundayGreekOrthodox##&
Invoke with
a[2010]
Output
4/4/2010
Me too: I don't see the point in not using built-in functions.
Java - 252 196 190 chars
Update 1: The first algo was for Western Gregorian Easter. Fixed to Eastern Julian Easter now. Saved 56 chars :)
Update 2: Zero padding seem to not be required. Saved 4 chars.
class E{public static void main(String[]a){long y=new Long(a[0]),b=(y%19*19+15)%30,c=b+(y%4*2+y%7*4-b+34)%7+(y>1899&y<2100?128:115),m=c/31;System.out.printf("%d/%d/%d",c%31+(m<5?0:1),m,y);}}
With newlines
class E{
public static void main(String[]a){
long y=new Long(a[0]),
b=(y%19*19+15)%30,
c=b+(y%4*2+y%7*4-b+34)%7+(y>1899&y<2100?128:115),
m=c/31;
System.out.printf("%d/%d/%d",c%31+(m<5?0:1),m,y);
}
}
JavaScript (196 characters)
Using the Meeus Julian algorithm. This implementation assumes that a valid four-digit year was given.
y=~~prompt();d=(19*(y%19)+15)%30;x=d+(2*(y%4)+4*(y%7)-d+34)%7+114;m=~~(x/31);d=x%31+1;if(y>1899&&y<2100){d+=13;if(m==3&&d>31){d-=31;m++}if(m==4&&d>30){d-=30;m++}}alert((d<10?"0"+d:d)+"/0"+m+"/"+y)
Delphi 377 335 317 characters
Single line:
var y,c,n,i,j,m:integer;begin Val(ParamStr(1),y,n);c:=y div 100;n:=y-19*(y div 19);i:=c-c div 4-(c-((c-17)div 25))div 3+19*n+15;i:=i-30*(i div 30);i:=i-(i div 28 )*(1-(i div 28)*(29 div(i+1))*((21 -n)div 11));j:=y+y div 4 +i+2-c+c div 4;j:=j-7*(j div 7);m:=3+(i-j+40 )div 44;Write(i-j+28-31*(m div 4),'/',m,'/',y)end.
Formatted:
var
y,c,n,i,j,m:integer;
begin
Val(ParamStr(1),y,n);
c:=y div 100;
n:=y-19*(y div 19);
i:=c-c div 4-(c-((c-17)div 25))div 3+19*n+15;
i:=i-30*(i div 30);
i:=i-(i div 28 )*(1-(i div 28)*(29 div(i+1))*((21 -n)div 11));
j:=y+y div 4 +i+2-c+c div 4;j:=j-7*(j div 7);
m:=3+(i-j+40 )div 44;
Write(i-j+28-31*(m div 4),'/',m,'/',y)
end.
Tcl
Eastern Easter
(116 chars)
puts [expr 1+[incr d [expr ([set y $argv]%4*2+$y%7*4-[
set d [expr ($y%19*19+15)%30]]+34)%7+123]]%30]/[expr $d/30]/$y
Uses the Meeus algorithm. Takes the year as a command line argument, produces Eastern easter. Could be a one-liner, but it's slightly more readable when split...
Western Easter
(220 chars before splitting over lines)
interp alias {} tcl::mathfunc::s {} set;puts [expr [incr 3 [expr {
s(2,(s(4,$argv)%100/4*2-s(3,(19*s(0,$4%19)+s(1,$4/100)-$1/4-($1-($1+8)/25+46)
/3)%30)+$1%4*2-$4%4+4)%7)-($0+11*$3+22*$2)/451*7+114}]]%31+1]/[expr $3/31]/$4
Uses the Anonymous algorithm.
COBOL, 1262 chars
WORKING-STORAGE SECTION.
01 V-YEAR PIC S9(04) VALUE 2010.
01 V-DAY PIC S9(02) VALUE ZERO.
01 V-EASTERDAY PIC S9(04) VALUE ZERO.
01 V-CENTURY PIC S9(02) VALUE ZERO.
01 V-GOLDEN PIC S9(04) VALUE ZERO.
01 V-GREGORIAN PIC S9(04) VALUE ZERO.
01 V-CLAVIAN PIC S9(04) VALUE ZERO.
01 V-FACTOR PIC S9(06) VALUE ZERO.
01 V-EPACT PIC S9(06) VALUE ZERO.
PROCEDURE DIVISION
XX-CALCULATE EASTERDAY.
COMPUTE V-CENTURY = (V-YEAR / 100) + 1
COMPUTE V-GOLDEN= FUNCTION MOD(V-YEAR, 19) + 1
COMPUTE V-GREGORIAN = (V-CENTURY * 3) / 4 - 12
COMPUTE V-CLAVIAN
= (V-CENTURY * 8 + 5) / 25 - 5 - V-GREGORIAN
COMPUTE V-FACTOR
= (V-YEAR * 5) / 4 - V-GREGORIAN - 10
COMPUTE V-EPACT
= FUNCTION MOD((V-GOLDEN * 11 + 20 + V-CLAVIAN), 30)
IF V-EPACT = 24
ADD 1 TO V-EPACT
ELSE
IF V-EPACT = 25
IF V-GOLDEN > 11
ADD 1 TO V-EPACT
END-IF
END-IF
END-IF
COMPUTE V-DAY = 44 - V-EPACT
IF V-DAY < 21
ADD 30 TO V-DAY
END-IF
COMPUTE V-DAY
= V-DAY + 7 - (FUNCTION MOD((V-DAY + V-FACTOR), 7))
IF V-DAY <= 31
ADD 300 TO V-DAY GIVING V-EASTERDAY
ELSE
SUBTRACT 31 FROM V-DAY
ADD 400 TO V-DAY GIVING V-EASTERDAY
END-IF
.
XX-EXIT.
EXIT.
Note: Not mine, but I like it
EDIT: I added a char count with spaces but I don't know how spacing works in COBOL so I didn't change anything from original. ~vlad003
UPDATE: I've found where the OP got this code: http://www.tek-tips.com/viewthread.cfm?qid=31746&page=112. I'm just putting this here because the author deserves it. ~vlad003
C, 128 121 98 characters
Back to Meeus' algorithm. Computing the day in Julian, but adjusting for Gregorian (this still seems naive to me, but I cannot find a shorter alternative).
main(y,v){int d=(y%19*19+15)%30;d+=(y%4*2+y%7*4-d+34)%7+128;printf("%d/%d/%d",d%31+d/155,d/31,y);}
I have not found a case where floor(d/31) would actually be needed. Also, to account for dates in May, the m in Meeus' algorithm must be at least 5, therefore the DoM is greater than 154, hence the division.
The year is supplied as the number of program invocation arguments plus one, ie. for 1996 you must provide 1995 arguments. The range of ARG_MAX on modern systems is more than enough for this.
PS. I see Gabe has come to the same implementation in Python 2.3, surpassing me by one character. Aw. :(
PPS. Anybody looking at a tabular method for 1800-2099?
Edit - Shortened Gabe's answer to 88 characters:
y=input()
d=(y%19*19+15)%30
d+=(y%4*2+y%7*4-d+34)%7+128
print"%d/%d/%d"%(d%31+d/155,d/31,y)
BASIC, 973 chars
Sub EasterDate (d, m, y)
Dim FirstDig, Remain19, temp 'intermediate results
Dim tA, tB, tC, tD, tE 'table A to E results
FirstDig = y \ 100 'first 2 digits of year
Remain19 = y Mod 19 'remainder of year / 19
' calculate PFM date
temp = (FirstDig - 15) \ 2 + 202 - 11 * Remain19
Select Case FirstDig
Case 21, 24, 25, 27 To 32, 34, 35, 38
temp = temp - 1
Case 33, 36, 37, 39, 40
temp = temp - 2
End Select
temp = temp Mod 30
tA = temp + 21
If temp = 29 Then tA = tA - 1
If (temp = 28 And Remain19 > 10) Then tA = tA - 1
'find the next Sunday
tB = (tA - 19) Mod 7
tC = (40 - FirstDig) Mod 4
If tC = 3 Then tC = tC + 1
If tC > 1 Then tC = tC + 1
temp = y Mod 100
tD = (temp + temp \ 4) Mod 7
tE = ((20 - tB - tC - tD) Mod 7) + 1
d = tA + tE
'return the date
If d > 31 Then
d = d - 31
m = 4
Else
m = 3
End If
End Sub
Credit: Astronomical Society of South Australia
EDIT: I added a char count but I think many spaces could be removed; I don't know BASIC so I didn't make any changes to the code. ~vlad003
I'm not going to implement it, but I'd like to see one where the code e-mails the Pope, scans any answer that comes back for a date, and returns that.
Admittedly, the calling process may be blocked for a while.
Javascript 125 characters
This will handle years 1900 - 2199. Some of the other implementations cannot handle the year 2100 correctly.
y=prompt();k=(y%19*19+15)%30;e=(y%4*2+y%7*4-k+34)%7+k+127;m=~~(e/31);d=e%31+m-4+(y>2099);alert((d+=d<30||++m-34)+"/"+m+"/"+y)
Ungolfed..ish
// get the year to check.
y=prompt();
// do something crazy.
k=(y%19*19+15)%30;
// do some more crazy...
e=(y%4*2+y%7*4-k+34)%7+k+127;
// estimate the month. p.s. The "~~" is like Math.floor
m=~~(e/31);
// e % 31 => get the day
d=e%31;
if(m>4){
d += 1;
}
if(y > 2099){
d += 1;
}
// if d is less than 30 days add 1
if(d<30){
d += 1;
}
// otherwise, change month to May
// and adjusts the days to match up with May.
// e.g., 32nd of April is 2nd of May
else{
m += 1;
d = m - 34 + d;
}
// alert the result!
alert(d + "/" + m + "/" + y);
A fix for dates up to 2399.
I'm sure there is a way to algorithmically calculate dates beyond this but I don't want to figure it out.
y=prompt();k=(y%19*19+15)%30;e=(y%4*2+y%7*4-k+34)%7+k+127;m=~~(e/31);d=e%31+m-4+(y<2200?0:~~((y-2000)/100));alert((d+=d<30||++m-34)+"/"+m+"/"+y)
'VB .Net implementation of:
'http://aa.usno.navy.mil/faq/docs/easter.php
Dim y As Integer = 2010
Dim c, d, i, j, k, l, m, n As Integer
c = y \ 100
n = y - 19 * (y \ 19)
k = (c - 17) \ 25
i = c - c \ 4 - (c - k) \ 3 + 19 * n + 15
i = i - 30 * (i \ 30)
i = i - (i \ 28) * (1 - (i \ 28) * (29 \ (i + 1)) * ((21 - n) \ 11))
j = y + y \ 4 + i + 2 - c + c \ 4
j = j - 7 * (j \ 7)
l = i - j
m = 3 + (l + 40) \ 44
d = l + 28 - 31 * (m \ 4)
Easter = DateSerial(y, m, d)