Need Help. I have an associative array which has the days of the week. I know very little about arrays. Each day has a 1 or 0 in the array below. I am trying to output dates and use them to generate tasks. I'm sure can this be done easily, but I lack the experience.
I want to output only dates which have 1's as shown in the array below.
The first task is due in 4 days.
I need to view dates up to 3 days ahead, so if today is Tuesday, and start is on Friday, then the Friday task date won't appear until Wednesday.
Today := A_now
WeekDays_Array := {Sun: 0, Mon: 0, Tue: 1, Wed: 0, Thu: 1, Fri: 1, Sat: 0}
I am pretty sure this is most of it. The suggestion to use the array above made the most sense.
The script uses Wkday (which is A_Now) as the start day but I think that can be changed by substituting it for a specific start day
PastDue := []
DueBy := []
;~ Weekday_Array := {Sunday: 0, Monday: 0, Tuesday: 1, Wednesday: 0, Thursday: 1, Friday: 1, Saturday: 0}
Weekday_Array := [1,1,1,1,1,1,1] ;Represents Sun-Saturday
AssignTask:
FormatTime, WkDay, MyTime, WDay
For i, value in Weekday_Array{
DueDate =
if (i > WkDay && Value = 1){
x++
DueDate += (x), days
FormatTime, DueDate, % DueDate, MM/dd/yy
DueBy.InsertAt(i,DueDate)
}
if (i = WkDay && Value = 1){
FormatTime, DueDate, % A_Now, MM/dd/yy
DueBy.InsertAt(i,DueDate)
}
if (i < WkDay && Value = 1){
y--
Pastdate =
PastDate += (y) , days
NewDate := PastDate
NewDate += 7, days
FormatTime, PastDate, % PastDate, MM/dd/yy
FormatTime, NewDate, % NewDate, MM/dd/yy
PastDue.InsertAt(i,PastDate)
DueBy.insertAt(i,NewDate)
}
}
For i, PastDue in PastDue
PastDueDates .= PastDue "`n"
Sort, PastDueDates
PastDueDates := "Past due dates so far this week `n`n" PastDueDates
MsgBox, 0x1000,, % PastDueDates
For i, DueDate in DueBy
DueDates .= DueDate "`n"
Sort, DueDates
DueDates := "All upcoming due dates based criteria `n`n" DueDates
MsgBox, 0x1000,, % DueDates
sort, DueDates
FormatTime, xDay1, % A_Now, MM/dd/yy
xDay2 += 1, days
FormatTime, xDay2, % xDay2, MM/dd/yy
xDay3 += 2, days
FormatTime, xDay3, % xDay3, MM/dd/yy
For i, DueDate in DueBy{
if (DueDate = xDay1 || DueDate = xDay2 || DueDate = xDay3)
XDays .= DueDate "`n"
}
xDays := "Only view the next 3 days from today `n`n" xDays
MsgBox, 0x1000,, % xDays
;~ return
*esc::
ExitApp
return
I need to convert an arbitrary amount of milliseconds into Days, Hours, Minutes Second.
For example: 10 Days, 5 hours, 13 minutes, 1 second.
Well, since nobody else has stepped up, I'll write the easy code to do this:
x = ms / 1000
seconds = x % 60
x /= 60
minutes = x % 60
x /= 60
hours = x % 24
x /= 24
days = x
I'm just glad you stopped at days and didn't ask for months. :)
Note that in the above, it is assumed that / represents truncating integer division. If you use this code in a language where / represents floating point division, you will need to manually truncate the results of the division as needed.
Let A be the amount of milliseconds. Then you have:
seconds=(A/1000)%60
minutes=(A/(1000*60))%60
hours=(A/(1000*60*60))%24
and so on (% is the modulus operator).
Hope this helps.
Both solutions below use javascript (I had no idea the solution was language agnostic!). Both solutions will need to be extended if capturing durations > 1 month.
Solution 1: Use the Date object
var date = new Date(536643021);
var str = '';
str += date.getUTCDate()-1 + " days, ";
str += date.getUTCHours() + " hours, ";
str += date.getUTCMinutes() + " minutes, ";
str += date.getUTCSeconds() + " seconds, ";
str += date.getUTCMilliseconds() + " millis";
console.log(str);
Gives:
"6 days, 5 hours, 4 minutes, 3 seconds, 21 millis"
Libraries are helpful, but why use a library when you can re-invent the wheel! :)
Solution 2: Write your own parser
var getDuration = function(millis){
var dur = {};
var units = [
{label:"millis", mod:1000},
{label:"seconds", mod:60},
{label:"minutes", mod:60},
{label:"hours", mod:24},
{label:"days", mod:31}
];
// calculate the individual unit values...
units.forEach(function(u){
millis = (millis - (dur[u.label] = (millis % u.mod))) / u.mod;
});
// convert object to a string representation...
var nonZero = function(u){ return dur[u.label]; };
dur.toString = function(){
return units
.reverse()
.filter(nonZero)
.map(function(u){
return dur[u.label] + " " + (dur[u.label]==1?u.label.slice(0,-1):u.label);
})
.join(', ');
};
return dur;
};
Creates a "duration" object, with whatever fields you require.
Formatting a timestamp then becomes simple...
console.log(getDuration(536643021).toString());
Gives:
"6 days, 5 hours, 4 minutes, 3 seconds, 21 millis"
Apache Commons Lang has a DurationFormatUtils that has very helpful methods like formatDurationWords.
You should use the datetime functions of whatever language you're using, but, just for fun here's the code:
int milliseconds = someNumber;
int seconds = milliseconds / 1000;
int minutes = seconds / 60;
seconds %= 60;
int hours = minutes / 60;
minutes %= 60;
int days = hours / 24;
hours %= 24;
This is a method I wrote. It takes an integer milliseconds value and returns a human-readable String:
public String convertMS(int ms) {
int seconds = (int) ((ms / 1000) % 60);
int minutes = (int) (((ms / 1000) / 60) % 60);
int hours = (int) ((((ms / 1000) / 60) / 60) % 24);
String sec, min, hrs;
if(seconds<10) sec="0"+seconds;
else sec= ""+seconds;
if(minutes<10) min="0"+minutes;
else min= ""+minutes;
if(hours<10) hrs="0"+hours;
else hrs= ""+hours;
if(hours == 0) return min+":"+sec;
else return hrs+":"+min+":"+sec;
}
function convertTime(time) {
var millis= time % 1000;
time = parseInt(time/1000);
var seconds = time % 60;
time = parseInt(time/60);
var minutes = time % 60;
time = parseInt(time/60);
var hours = time % 24;
var out = "";
if(hours && hours > 0) out += hours + " " + ((hours == 1)?"hr":"hrs") + " ";
if(minutes && minutes > 0) out += minutes + " " + ((minutes == 1)?"min":"mins") + " ";
if(seconds && seconds > 0) out += seconds + " " + ((seconds == 1)?"sec":"secs") + " ";
if(millis&& millis> 0) out += millis+ " " + ((millis== 1)?"msec":"msecs") + " ";
return out.trim();
}
In java
public static String formatMs(long millis) {
long hours = TimeUnit.MILLISECONDS.toHours(millis);
long mins = TimeUnit.MILLISECONDS.toMinutes(millis);
long secs = TimeUnit.MILLISECONDS.toSeconds(millis);
return String.format("%dh %d min, %d sec",
hours,
mins - TimeUnit.HOURS.toMinutes(hours),
secs - TimeUnit.MINUTES.toSeconds(mins)
);
}
Gives something like this:
12h 1 min, 34 sec
I would suggest using whatever date/time functions/libraries your language/framework of choice provides. Also check out string formatting functions as they often provide easy ways to pass date/timestamps and output a human readable string format.
Your choices are simple:
Write the code to do the conversion (ie, divide by milliSecondsPerDay to get days and use the modulus to divide by milliSecondsPerHour to get hours and use the modulus to divide by milliSecondsPerMinute and divide by 1000 for seconds. milliSecondsPerMinute = 60000, milliSecondsPerHour = 60 * milliSecondsPerMinute, milliSecondsPerDay = 24 * milliSecondsPerHour.
Use an operating routine of some kind. UNIX and Windows both have structures that you can get from a Ticks or seconds type value.
Long serverUptimeSeconds =
(System.currentTimeMillis() - SINCE_TIME_IN_MILLISECONDS) / 1000;
String serverUptimeText =
String.format("%d days %d hours %d minutes %d seconds",
serverUptimeSeconds / 86400,
( serverUptimeSeconds % 86400) / 3600 ,
((serverUptimeSeconds % 86400) % 3600 ) / 60,
((serverUptimeSeconds % 86400) % 3600 ) % 60
);
Why just don't do something like this:
var ms = 86400;
var seconds = ms / 1000; //86.4
var minutes = seconds / 60; //1.4400000000000002
var hours = minutes / 60; //0.024000000000000004
var days = hours / 24; //0.0010000000000000002
And dealing with float precision e.g. Number(minutes.toFixed(5)) //1.44
I'm not able to comment first answer to your question, but there's a small mistake. You should use parseInt or Math.floor to convert floating point numbers to integer, i
var days, hours, minutes, seconds, x;
x = ms / 1000;
seconds = Math.floor(x % 60);
x /= 60;
minutes = Math.floor(x % 60);
x /= 60;
hours = Math.floor(x % 24);
x /= 24;
days = Math.floor(x);
Personally, I use CoffeeScript in my projects and my code looks like that:
getFormattedTime : (ms)->
x = ms / 1000
seconds = Math.floor x % 60
x /= 60
minutes = Math.floor x % 60
x /= 60
hours = Math.floor x % 24
x /= 24
days = Math.floor x
formattedTime = "#{seconds}s"
if minutes then formattedTime = "#{minutes}m " + formattedTime
if hours then formattedTime = "#{hours}h " + formattedTime
formattedTime
This is a solution. Later you can split by ":" and take the values of the array
/**
* Converts milliseconds to human readeable language separated by ":"
* Example: 190980000 --> 2:05:3 --> 2days 5hours 3min
*/
function dhm(t){
var cd = 24 * 60 * 60 * 1000,
ch = 60 * 60 * 1000,
d = Math.floor(t / cd),
h = '0' + Math.floor( (t - d * cd) / ch),
m = '0' + Math.round( (t - d * cd - h * ch) / 60000);
return [d, h.substr(-2), m.substr(-2)].join(':');
}
var delay = 190980000;
var fullTime = dhm(delay);
console.log(fullTime);
Long expireTime = 69l;
Long tempParam = 0l;
Long seconds = math.mod(expireTime, 60);
tempParam = expireTime - seconds;
expireTime = tempParam/60;
Long minutes = math.mod(expireTime, 60);
tempParam = expireTime - minutes;
expireTime = expireTime/60;
Long hours = math.mod(expireTime, 24);
tempParam = expireTime - hours;
expireTime = expireTime/24;
Long days = math.mod(expireTime, 30);
system.debug(days + '.' + hours + ':' + minutes + ':' + seconds);
This should print: 0.0:1:9
Here's my solution using TimeUnit.
UPDATE: I should point out that this is written in groovy, but Java is almost identical.
def remainingStr = ""
/* Days */
int days = MILLISECONDS.toDays(remainingTime) as int
remainingStr += (days == 1) ? '1 Day : ' : "${days} Days : "
remainingTime -= DAYS.toMillis(days)
/* Hours */
int hours = MILLISECONDS.toHours(remainingTime) as int
remainingStr += (hours == 1) ? '1 Hour : ' : "${hours} Hours : "
remainingTime -= HOURS.toMillis(hours)
/* Minutes */
int minutes = MILLISECONDS.toMinutes(remainingTime) as int
remainingStr += (minutes == 1) ? '1 Minute : ' : "${minutes} Minutes : "
remainingTime -= MINUTES.toMillis(minutes)
/* Seconds */
int seconds = MILLISECONDS.toSeconds(remainingTime) as int
remainingStr += (seconds == 1) ? '1 Second' : "${seconds} Seconds"
A flexible way to do it :
(Not made for current date but good enough for durations)
/**
convert duration to a ms/sec/min/hour/day/week array
#param {int} msTime : time in milliseconds
#param {bool} fillEmpty(optional) : fill array values even when they are 0.
#param {string[]} suffixes(optional) : add suffixes to returned values.
values are filled with missings '0'
#return {int[]/string[]} : time values from higher to lower(ms) range.
*/
var msToTimeList=function(msTime,fillEmpty,suffixes){
suffixes=(suffixes instanceof Array)?suffixes:[]; //suffixes is optional
var timeSteps=[1000,60,60,24,7]; // time ranges : ms/sec/min/hour/day/week
timeSteps.push(1000000); //add very big time at the end to stop cutting
var result=[];
for(var i=0;(msTime>0||i<1||fillEmpty)&&i<timeSteps.length;i++){
var timerange = msTime%timeSteps[i];
if(typeof(suffixes[i])=="string"){
timerange+=suffixes[i]; // add suffix (converting )
// and fill zeros :
while( i<timeSteps.length-1 &&
timerange.length<((timeSteps[i]-1)+suffixes[i]).length )
timerange="0"+timerange;
}
result.unshift(timerange); // stack time range from higher to lower
msTime = Math.floor(msTime/timeSteps[i]);
}
return result;
};
NB : you could also set timeSteps as parameter if you want to control the time ranges.
how to use (copy an test):
var elsapsed = Math.floor(Math.random()*3000000000);
console.log( "elsapsed (labels) = "+
msToTimeList(elsapsed,false,["ms","sec","min","h","days","weeks"]).join("/") );
console.log( "half hour : "+msToTimeList(elsapsed,true)[3]<30?"first":"second" );
console.log( "elsapsed (classic) = "+
msToTimeList(elsapsed,false,["","","","","",""]).join(" : ") );
I suggest to use http://www.ocpsoft.org/prettytime/ library..
it's very simple to get time interval in human readable form like
PrettyTime p = new PrettyTime();
System.out.println(p.format(new Date()));
it will print like "moments from now"
other example
PrettyTime p = new PrettyTime());
Date d = new Date(System.currentTimeMillis());
d.setHours(d.getHours() - 1);
String ago = p.format(d);
then string ago = "1 hour ago"
In python 3 you could achieve your goal by using the following snippet:
from datetime import timedelta
ms = 536643021
td = timedelta(milliseconds=ms)
print(str(td))
# --> 6 days, 5:04:03.021000
Timedelta documentation: https://docs.python.org/3/library/datetime.html#datetime.timedelta
Source of the __str__ method of timedelta str: https://github.com/python/cpython/blob/33922cb0aa0c81ebff91ab4e938a58dfec2acf19/Lib/datetime.py#L607
Here is more precise method in JAVA , I have implemented this simple logic , hope this will help you:
public String getDuration(String _currentTimemilliSecond)
{
long _currentTimeMiles = 1;
int x = 0;
int seconds = 0;
int minutes = 0;
int hours = 0;
int days = 0;
int month = 0;
int year = 0;
try
{
_currentTimeMiles = Long.parseLong(_currentTimemilliSecond);
/** x in seconds **/
x = (int) (_currentTimeMiles / 1000) ;
seconds = x ;
if(seconds >59)
{
minutes = seconds/60 ;
if(minutes > 59)
{
hours = minutes/60;
if(hours > 23)
{
days = hours/24 ;
if(days > 30)
{
month = days/30;
if(month > 11)
{
year = month/12;
Log.d("Year", year);
Log.d("Month", month%12);
Log.d("Days", days % 30);
Log.d("hours ", hours % 24);
Log.d("Minutes ", minutes % 60);
Log.d("Seconds ", seconds % 60);
return "Year "+year + " Month "+month%12 +" Days " +days%30 +" hours "+hours%24 +" Minutes "+minutes %60+" Seconds "+seconds%60;
}
else
{
Log.d("Month", month);
Log.d("Days", days % 30);
Log.d("hours ", hours % 24);
Log.d("Minutes ", minutes % 60);
Log.d("Seconds ", seconds % 60);
return "Month "+month +" Days " +days%30 +" hours "+hours%24 +" Minutes "+minutes %60+" Seconds "+seconds%60;
}
}
else
{
Log.d("Days", days );
Log.d("hours ", hours % 24);
Log.d("Minutes ", minutes % 60);
Log.d("Seconds ", seconds % 60);
return "Days " +days +" hours "+hours%24 +" Minutes "+minutes %60+" Seconds "+seconds%60;
}
}
else
{
Log.d("hours ", hours);
Log.d("Minutes ", minutes % 60);
Log.d("Seconds ", seconds % 60);
return "hours "+hours+" Minutes "+minutes %60+" Seconds "+seconds%60;
}
}
else
{
Log.d("Minutes ", minutes);
Log.d("Seconds ", seconds % 60);
return "Minutes "+minutes +" Seconds "+seconds%60;
}
}
else
{
Log.d("Seconds ", x);
return " Seconds "+seconds;
}
}
catch (Exception e)
{
Log.e(getClass().getName().toString(), e.toString());
}
return "";
}
private Class Log
{
public static void d(String tag , int value)
{
System.out.println("##### [ Debug ] ## "+tag +" :: "+value);
}
}
A solution using awk:
$ ms=10000001; awk -v ms=$ms 'BEGIN {x=ms/1000;
s=x%60; x/=60;
m=x%60; x/=60;
h=x%60;
printf("%02d:%02d:%02d.%03d\n", h, m, s, ms%1000)}'
02:46:40.001
This one leaves out 0 values. With tests.
const toTimeString = (value, singularName) =>
`${value} ${singularName}${value !== 1 ? 's' : ''}`;
const readableTime = (ms) => {
const days = Math.floor(ms / (24 * 60 * 60 * 1000));
const daysMs = ms % (24 * 60 * 60 * 1000);
const hours = Math.floor(daysMs / (60 * 60 * 1000));
const hoursMs = ms % (60 * 60 * 1000);
const minutes = Math.floor(hoursMs / (60 * 1000));
const minutesMs = ms % (60 * 1000);
const seconds = Math.round(minutesMs / 1000);
const data = [
[days, 'day'],
[hours, 'hour'],
[minutes, 'minute'],
[seconds, 'second'],
];
return data
.filter(([value]) => value > 0)
.map(([value, name]) => toTimeString(value, name))
.join(', ');
};
// Tests
const hundredDaysTwentyHoursFiftyMinutesThirtySeconds = 8715030000;
const oneDayTwoHoursEightMinutesTwelveSeconds = 94092000;
const twoHoursFiftyMinutes = 10200000;
const oneMinute = 60000;
const fortySeconds = 40000;
const oneSecond = 1000;
const oneDayTwelveSeconds = 86412000;
const test = (result, expected) => {
console.log(expected, '- ' + (result === expected));
};
test(readableTime(
hundredDaysTwentyHoursFiftyMinutesThirtySeconds
), '100 days, 20 hours, 50 minutes, 30 seconds');
test(readableTime(
oneDayTwoHoursEightMinutesTwelveSeconds
), '1 day, 2 hours, 8 minutes, 12 seconds');
test(readableTime(
twoHoursFiftyMinutes
), '2 hours, 50 minutes');
test(readableTime(
oneMinute
), '1 minute');
test(readableTime(
fortySeconds
), '40 seconds');
test(readableTime(
oneSecond
), '1 second');
test(readableTime(
oneDayTwelveSeconds
), '1 day, 12 seconds');