I don't understand why to change value of copy, change the value of the $scope :
var tmpmember = $scope.registration.member;
console.log($scope.registration.member.birth);
tmpmember.birth=$filter('date')($scope.registration.member.birth,'yyyy-MM-dd');
console.log(tmpmember.birth);
console.log($scope.registration.member.birth);
Output :
Thu Mar 11 1954 01:00:00 GMT+0100 (CET)
261 1954-03-11
262 1954-03-11
Someone could explain to me please ?
Many thanks
In the code you presented, you haven't made a copy of the object. Instead, you have created a second variable pointing to the same object instance.
Angular has a function you can use if you truly wish to have a copy rather than an additional reference, angular.copy. https://docs.angularjs.org/api/ng/function/angular.copy#!/
var tmpmember = angular.copy($scope.registration.member);
console.log($scope.registration.member.birth);
tmpmember.birth = $filter('date')($scope.registration.member.birth, 'yyyy-MM-dd');
console.log(tmpmember.birth);
console.log($scope.registration.member.birth);
Result:
Thu Mar 11 1954 01:00:00 GMT+0100 (CET)
261 1954-03-11
Thu Mar 11 1954 01:00:00 GMT+0100 (CET)
Related
so... i need to take times from dates inside Array
so for example I have an array like this
a = [
Thu, 17 Mar 2022 10:00:00.000000000 KST +09:00,
Thu, 17 Mar 2022 10:00:00.000000000 KST +09:00,
Thu, 17 Mar 2022 14:00:00.000000000 KST +09:00,
Thu, 17 Mar 2022 14:00:00.000000000 KST +09:00,
Thu, 17 Mar 2022 17:00:00.000000000 KST +09:00]
and wanted to have result of
a = ["10:00", "10:00", "14:00", "14:00", "17:00"]
So i was trying this
can_choose =[];
a.each_with_index do |time| strftime("%H:%M")
can_choose <<|time|
but doesn't works at all...
where should I have to fix??
You can also extract the year, month, day the same way
https://ruby-doc.org/stdlib-3.1.1/libdoc/date/rdoc/Date.html
a = [
'Thu, 17 Mar 2022 10:00:00.000000000 KST +09:00',
'Thu, 17 Mar 2022 10:00:00.000000000 KST +09:00',
'Thu, 17 Mar 2022 14:00:00.000000000 KST +09:00',
'Thu, 17 Mar 2022 14:00:00.000000000 KST +09:00',
'Thu, 17 Mar 2022 17:00:00.000000000 KST +09:00']
can_choose =[]
a.map do |time|
t = DateTime.parse(time)
can_choose << t.strftime("%k:%M")
end
p can_choose
=> ["10:00", "10:00", "14:00", "14:00", "17:00"]
Ruby is all about message passing. The syntax to send a message is:
receiver.message(argument)
strftime is such message, but it needs a proper receiver. So if you have some Time instance, e.g.:
time = Time.parse('2022-03-17 10:00:00 +0900')
you'd write:
time.strftime('%H:%M') #=> "10:00"
with time being the receiver, strftime being the message and '%H:%M' being the argument.
You can use the above code in an each loop like this:
can_choose = []
a.each do |time|
can_choose << time.strftime('%H:%M')
end
Or you could use map to convert your array to another array:
can_choose = a.map { |time| time.strftime('%H:%M') }
The curly braces here { ... } are equivalent to the do ... end block above.
I would simple go with:
can_choose = a.map { |datetime| datetime.strftime('%H:%M') }
If you need only hours and minutes in 24h format, just use %R directive with Time#strftime or DateTime#strftime
can_choose = a.map { |time| time.strftime('%R') }
mktime returns for july 3rd 1941 (00:00:00) and july 4th 1941 (00:00:00) are unexpected.
The difference between the two is 82800 seconds, lacking a full hour (3600).
The C program diff1941.c (see below) shows the following :
$> diff1941
july3=-899337600i
diff:82800 should be 86400
At first I thought it was a TZ Database hour shift, but as far as I understand, and according to zdump command, there is no such shift for 1941.
zdump -v -c 1940,1943 /etc/localtime
/etc/localtime Sun Feb 25 01:59:59 1940 UT = Sun Feb 25 01:59:59 1940 WET isdst=0 gmtoff=0
/etc/localtime Sun Feb 25 02:00:00 1940 UT = Sun Feb 25 03:00:00 1940 WEST isdst=1 gmtoff=3600
/etc/localtime Fri Jun 14 21:59:59 1940 UT = Fri Jun 14 22:59:59 1940 WEST isdst=1 gmtoff=3600
/etc/localtime Fri Jun 14 22:00:00 1940 UT = Sat Jun 15 00:00:00 1940 CEST isdst=1 gmtoff=7200
/etc/localtime Mon Nov 2 00:59:59 1942 UT = Mon Nov 2 02:59:59 1942 CEST isdst=1 gmtoff=7200
/etc/localtime Mon Nov 2 01:00:00 1942 UT = Mon Nov 2 02:00:00 1942 CET isdst=0 gmtoff=3600
So at this point I am confused. Either my program has a bug that I can not see (possible), or there is a bug in lib C mktime function(unlikely), or there is something subtle in the TZ database and I can not find it (probable): what do you think of it ?
I am using:
Ubuntu 20.04 64 bits,
libc 2.31-0ubuntu9,
tzdata 2019c-3ubuntu1
/etc/localtime points on /usr/share/zoneinfo/Europe/Paris
diff1941.c:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
long int stamp(int d,int m,int y)
{
struct tm date;
memset(&date,0,sizeof(date));
date.tm_mday=d;
date.tm_mon=m-1;
date.tm_year=y-1900;
return mktime(&date);
}
int main(int argc, char **argv)
{
if (argc>1)
setenv("TZ","0",1);
long int july3=stamp(3,7,1941);
long int july4=stamp(4,7,1941);
printf("july3=%ldi\n",july3);
printf("diff:%ld should be 86400\n",july4-july3);
}
Usually, when you see 1 hour difference in time, that means you should take a look at daylight saving time settings.
On both dates 3rd July 1941 and 4th July 1941 daylight saving time was in effect in France. You specify tm_isdst = 0, that means the daylight saving time is not in effect for your dates. So your dates are invalid - there was no such time as 3rd July 1941 with 00:00:00 with no DST.
Glibc mktime tries it's best to determine what time do you have in mind. Actually it determines the first of the dates as 3rd July 1941 02:00:00 and the second of the dates as 4th July 1941 01:00:00. The difference is one day minus one hour.
Either set isdst=-1 to let mktime "automagically" determine the current DST for your input times. In France it was DST all the time in 1941, it will determine isdst=1. Or explicit specify that you want DST by setting date.isdst=1.
I am pushing the dates of the week into an array.
If you can refer the code, in the // good value line
The array has the correct value
But each time the dates.setDate(dates.getDate() + 1 );
executes
All the array values are automatically updated with the new value.
Instead of just pushing the new element in the array, it pushes the new element in the array and replaces all the elements of the array with the new element
this.mondayDate = this.getMonday(this.viewDate);
let dates = this.mondayDate;
this.datesOfTheWeek = [];
this.datesOfTheWeek.push(this.mondayDate);
console.log(this.datesOfTheWeek);
for(let i in [1,2,3,4,5,6]){
console.log(this.datesOfTheWeek); // good value in the array
dates.setDate(dates.getDate() + 1 );
console.log(this.datesOfTheWeek); // bad value in the array
this.datesOfTheWeek.push(dates);
console.log(this.datesOfTheWeek);
}
console.log(this.datesOfTheWeek);
1st iteration: //contains only monday date- output from //bad value
Array(1) [Tue May 21 2019 15:17:46 GMT+0200 (heure d’été d’E…]
2nd iteration: // pushing tuesday date- output from //bad value
Array(2) [Wed May 22 2019 15:17:46 GMT+0200 (heure d’été d’E…, Wed May 22 2019 15:17:46 GMT+0200 (heure d’été d’E…]
The array value at the end is
Array(6) [Sun May 26 2019 15:17:46 GMT+0200 (heure d’été d’E…, Sun May 26 2019 15:17:46 GMT+0200 (heure d’été d’E…, Sun May 26 2019 15:17:46 GMT+0200 (heure d’été d’E…, Sun May 26 2019 15:17:46 GMT+0200 (heure d’été d’E…, Sun May 26 2019 15:17:46 GMT+0200 (heure d’été d’E…, Sun May 26 2019 15:17:46 GMT+0200 (heure d’été d’E…]
But it should contain the dates from may 20 to may 26
That's because dates looks to be a Date object, not a primitive (so, if you mutate it, all the references to it will point to the mutated value). You need to create a copy: instead of
dates.setDate(dates.getDate() + 1 );
console.log(this.datesOfTheWeek); // bad value in the array
this.datesOfTheWeek.push(dates);
do something like
let newDate = new Date(dates);
newDate.setDate(dates.getDate() + 1 );
console.log(this.datesOfTheWeek);
this.datesOfTheWeek.push(newDate);
How to find the most recent date from an array like the one below?
Tue Jun 2 17:59:54 GMT+0200 2013
Tue Jun 5 18:00:10 GMT+0200 2013
Tue Jun 1 12:27:14 GMT+0200 2013
Tue Jun 3 17:26:58 GMT+0200 2013
Tue Jun 9 17:27:49 GMT+0200 2013
Tue Jun 1 13:27:39 GMT+0200 2015
Tue Jun 3 12:27:59 GMT+0200 2013
Tue Jun 6 15:27:22 GMT+0200 2014
Tue Jun 2 17:27:30 GMT+0200 2014
Assuming your array is full of AS3 native Date objects, you could simply do this:
array.sortOn("time",Array.DESCENDING);
trace("Most Recent:",array[0]);
You cannot use array.sort (unless you use the Array.NUMERIC flag) because it will sort the string representation of the date. So all your days of the week would then be grouped together instead of the actual date.
If your dates are strings, then you will need to convert them to Date objects prior to sorting:
//assuming your posted array is in a var called 'stringArray'
var dateArray:Array = []; //a new array to hold the converted strings
for(var i:int=0;i<stringArray.length;i++){
dateArray.push(new Date(stringArray[i]));
}
dateArray.sortOn("time",Array.DESCENDING);
trace("Most Recent Date:",dateArray[0]);
To show this in a concrete example, here is your posted dates - copy paste this code to produce the same results:
var arr:Array = new Array(
new Date("Tue Jun 2 17:59:54 GMT+0200 2013"),
new Date("Tue Jun 5 18:00:10 GMT+0200 2013"),
new Date("Tue Jun 1 12:27:14 GMT+0200 2013"),
new Date("Tue Jun 3 17:26:58 GMT+0200 2013"),
new Date("Tue Jun 9 17:27:49 GMT+0200 2013"),
new Date("Tue Jun 1 13:27:39 GMT+0200 2015"),
new Date("Tue Jun 3 12:27:59 GMT+0200 2013"),
new Date("Tue Jun 6 15:27:22 GMT+0200 2014"),
new Date("Tue Jun 2 17:27:30 GMT+0200 2014")
);
arr.sort(Array.DESCENDING);
trace("SORT:");
traceDates();
arr.sortOn("time",Array.DESCENDING);
trace("\nSORT ON:");
traceDates();
function traceDates(){
for(var i:int=0;i<arr.length;i++){
trace(" ",arr[i].fullYear + "-" + arr[i].month + "-" + arr[i].day);
}
}
//OUTPUT:
/*
SORT:
2013-5-3
2013-5-0
2013-5-0
2013-5-6
2013-5-1
2013-5-1
2014-5-1
2015-5-1 //most recent date, second to LAST item in the array
2014-5-5
SORT ON:
2015-5-1 //June 1st is the most recent date (first item in the array)
2014-5-5
2014-5-1
2013-5-0
2013-5-3
2013-5-1
2013-5-1
2013-5-0
2013-5-6
*/
Are they Date objects?
If so, you can compare the time property of each. It will give you the number of milliseconds since Jan 1, 1970. The highest number will be the most recent.
Something along these lines:
var mostRecentDate:Date = dateArray[0];
for(var i:int = 0; i < dateArray.length; i++){
if(dateArray[i].time > mostRecentDate.time){
mostRecentDate = dateArray[i];
}
}
Date objects act like simple Number when it comes to sorting or comparison. All you have to do is treat them like Numbers. So taken from Cadin answer:
dateArray.sort();
var oldestDate:Date = dateArray[0];
Will get you the oldest Date while:
dateArray.sort(Array.DESCENDING);
var mostRecentDate:Date = dateArray[0];
Will get you the most recent one.
For LDMS, this is what I got:
var firstdate:Date = new Date();
var seconddate:Date = new Date();
var thirddate:Date = new Date();
seconddate.time = firstdate.time + 5000000;
thirddate.time = firstdate.time + 50000000;
trace(seconddate > firstdate)//true
trace(firstdate > seconddate)//false
trace(seconddate.time > firstdate.time)//true
var array:Array = [thirddate, firstdate, seconddate];
trace(array)
//Wed Jun 3 03:37:40 GMT-0400 2015,Tue Jun 2 13:44:20 GMT-0400 2015,Tue Jun 2 15:07:40 GMT-0400 2015
array.sort();
trace(array)
//Tue Jun 2 13:44:20 GMT-0400 2015,Tue Jun 2 15:07:40 GMT-0400 2015,Wed Jun 3 03:37:40 GMT-0400 2015
array.sort(Array.DESCENDING);
trace(array)
//Wed Jun 3 03:37:40 GMT-0400 2015,Tue Jun 2 15:07:40 GMT-0400 2015,Tue Jun 2 13:44:20 GMT-0400 2015
Sort the array and grab the first (descending) or last (ascending) element.
Edit: 2 down-votes because I didn't provide an example, or because people don't know you can sort dates? This works:
var dates:Array = [
"Tue Jun 2 17:59:54 GMT+0200 2013",
"Tue Jun 5 18:00:10 GMT+0200 2013",
"Tue Jun 1 12:27:14 GMT+0200 2013",
"Tue Jun 3 17:26:58 GMT+0200 2013",
"Tue Jun 9 17:27:49 GMT+0200 2013",
"Tue Jun 1 13:27:39 GMT+0200 2015",
"Tue Jun 3 12:27:59 GMT+0200 2013",
"Tue Jun 6 15:27:22 GMT+0200 2014",
"Tue Jun 2 17:27:30 GMT+0200 2014"
].map(function(s:String, i:int, a:Array):Date {
return new Date(s);
}).sort(Array.NUMERIC | Array.DESCENDING);
var latest:Date = dates[0]; // Mon Jun 1 07:27:39 GMT-0400 2015
The problem is the OP did not make it clear what kind of data they are working with (strings or Date objects) so the exact solution code is unknown.
(Language/API: Standard C 89 library and / or POSIX)
Probably a trivial question, but I've got a feeling that I'm missing something.
I need to implement this function:
time_t get_local_midnight_timestamp(time_t ts);
That is, we get arbitrary timestamp (from the last year, for example), and return it rounded up to the midnight of the same day.
The problem is that the function must be aware of DST switches and DST rules changes (like DST cancellation and/or extension).
The function must also be future-proof, and cope with weird TZ changes (like shift of time zone 30 minutes ahead etc.).
(The reason I need all this that I need to implement look up into some older statistics data.)
As far as I understand, naïve approach with zeroing out struct tm time fields would not work — precisely because of DST stuff (looks like in DST-change day there are two local midnight time_t timestamps).
Please point me in the right direction...
I doubt that it can be done with standard C 89, so POSIX-specific solutions are acceptable. If not POSIX, then something Debian-specific would do...
Update: Also: Something tells me that I should also take leap seconds in account. Maybe I should look into trying to directly use Tz database... (Which is rather sad — so much /perceived/ overhead for so small task.) ...Or not — seems that libc should use it, so maybe I'm just doing it wrong...
Update 2: Here is why I think that naïve solution does not work:
#include <stdio.h>
#include <time.h>
int main()
{
struct tm date_tm;
time_t date_start = 1301173200; /* Sunday 27 March 2011 0:00:00 AM MSK */
time_t midnight = 0;
char buf1[256];
char buf2[256];
int i = 0;
for (i = 0; i < 4 * 60 * 60; i += 60 * 60)
{
time_t date = date_start + i;
localtime_r(&date, &date_tm);
strftime(buf1, 256, "%c %Z", &date_tm);
date_tm.tm_sec = 0;
date_tm.tm_min = 0;
date_tm.tm_hour = 0;
midnight = mktime(&date_tm);
strftime(buf2, 256, "%c %Z", &date_tm);
printf("%d : %s -> %d : %s\n", (int)date, buf1, (int)midnight, buf2);
}
}
Output (local time was MSD at the moment when I run this):
$ gcc time.c && ./a.out
1301173200 : Sun Mar 27 00:00:00 2011 MSK -> 1301173200 : Sun Mar 27 00:00:00 2011 MSK
1301176800 : Sun Mar 27 01:00:00 2011 MSK -> 1301173200 : Sun Mar 27 00:00:00 2011 MSK
1301180400 : Sun Mar 27 03:00:00 2011 MSD -> 1301169600 : Sat Mar 26 23:00:00 2011 MSK
1301184000 : Sun Mar 27 04:00:00 2011 MSD -> 1301169600 : Sat Mar 26 23:00:00 2011 MSK
As you can see, two midnights.
I ran your code with the TZ environment variable set to "Europe/Moscow" and was able to reproduce your output. Here's what I think is going on:
On the first two lines, everything is fine. Then we "spring ahead" and 2 AM becomes 3 AM. Let's use gdb to break on entry to mktime and see what its argument is each time:
hour mday mon year wday yday isdst gmtoff tm_zone
0 27 2 111 0 85 0 10800 MSK
0 27 2 111 0 85 0 10800 MSK
0 27 2 111 0 85 1 14400 MSD
0 27 2 111 0 85 1 14400 MSD
So what has happened? Your code sets the hour to 0 each time, but this is a problem after the DST switch, because the impossible has happened: it is now "before" the DST switch in terms of the time of day, yet isdst is now set and gmtoff has been increased by one hour. By hacking up the time, you have "created" a time of midnight but with DST enabled, which is basically invalid.
You may now wonder, how can we get out of this mess? Do not despair! When you are adjusting the tm_hour field by hand, simply admit that you no longer know what the DST status is by setting tm_isdst to -1. This special value, which is documented in man localtime, means the DST status is "not available." So the computer will figure it out, and everything should work fine.
Here's my patch for your code:
date_tm.tm_hour = 0;
+ date_tm.tm_isdst = -1; /* we no longer know if it's DST or not */
Now I get this output, I hope is what you want:
$ TZ='Europe/Moscow' ./a.out
1301173200 : Sun Mar 27 00:00:00 2011 MSK -> 1301173200 : Sun Mar 27 00:00:00 2011 MSK
1301176800 : Sun Mar 27 01:00:00 2011 MSK -> 1301173200 : Sun Mar 27 00:00:00 2011 MSK
1301180400 : Sun Mar 27 03:00:00 2011 MSD -> 1301173200 : Sun Mar 27 00:00:00 2011 MSK
1301184000 : Sun Mar 27 04:00:00 2011 MSD -> 1301173200 : Sun Mar 27 00:00:00 2011 MSK