IOS Components From Date Changes Timezone - ios

I am using
NSDateComponents *components = [CURRENT_CALENDAR components:DATE_COMPONENTS fromDate:_startDate];
[components setHour:0];
[components setMinute:0];
[components setSecond:0];
_date = [CURRENT_CALENDAR dateFromComponents:components];
With dates I receive from an API.
The _date returns 2 different outputs depending on the calendar day:
2016-01-04 05:00:00 +0000
2015-10-26 04:00:00 +0000
As if there was a change in time zone.
Is there a reason the time of _date changes from 5 to 4 ?Is there something to prevent that?
Problem is that unexpected time offset (-1) reflects in all the other dates I create with dateFromComponents:components
Output for different dates showing the offset
2016-01-04 05:00:00 +0000
2015-12-21 05:00:00 +0000
2015-12-14 05:00:00 +0000
2015-12-07 05:00:00 +0000
2015-11-23 05:00:00 +0000
2015-11-16 05:00:00 +0000
2015-11-09 05:00:00 +0000
2015-11-02 05:00:00 +0000
2015-10-26 04:00:00 +0000
2015-10-19 04:00:00 +0000
2015-10-22 04:00:00 +0000
2015-10-01 04:00:00 +0000
2015-09-24 04:00:00 +0000

Related

Get hours an minutesfrom NSDate [duplicate]

This question already has answers here:
Getting date from [NSDate date] off by a few hours
(3 answers)
Closed 6 years ago.
I saved a date in a sqlite database. Know I try to get the hours and the minutes. But the hours are shifted by 2.
print(calendar.timeZone)
while result.next() {
var hour = 0
var minute = 0
let calendar = NSCalendar.currentCalendar()
if #available(iOS 8.0, *) {
calendar.getHour(&hour, minute: &minute, second: nil, nanosecond: nil, fromDate: result.dateForColumn("time"))
print(result.dateForColumn("time"))
print("the hour is \(hour) and minute is \(minute)")
}
}
I get the following output:
Europe/Berlin (GMT+2) offset 7200 (Daylight)
2016-08-17 18:44:57 +0000
the hour is 20 and minute is 44
2016-08-18 18:44:57 +0000
the hour is 20 and minute is 44
2016-08-19 15:44:57 +0000
the hour is 17 and minute is 44
2016-08-18 16:44:57 +0000
the hour is 18 and minute is 44
2016-08-17 18:44:57 +0000
the hour is 20 and minute is 44
2016-08-18 18:44:57 +0000
the hour is 20 and minute is 44
2016-08-19 15:44:57 +0000
the hour is 17 and minute is 44
2016-08-18 16:44:57 +0000
the hour is 18 and minute is 44
The timezone is correct. I tryed two other solutions. But it is always the same problem.
The result.dateForColumn("time") is in UTC since you have +0000 whereas the second output is in another timezone (Europe/Berlin (GMT+2)), so the date is the same.

Get first day of week of year in Objective-C

I'm trying to find the first day of weeks using DateTools like so:
for (NSInteger week = 46; week <= 53; week++) {
NSDate *tempDate = [NSDate dateWithString:[NSString stringWithFormat:#"2015-%d", (int)week] formatString:#"Y-w"];
NSLog(#"INFO: tempDate: %#, day: %.2d, week: %d", tempDate, (int)[tempDate day], (int)week);
}
for (NSInteger week = 1; week <= 5; week++) {
NSDate *tempDate = [NSDate dateWithString:[NSString stringWithFormat:#"2016-%d", (int)week] formatString:#"Y-w"];
NSLog(#"INFO: tempDate: %#, day: %.2d, week: %d", tempDate, (int)[tempDate day], (int)week);
}
and I get this output:
INFO: tempDate: 2015-11-07 22:00:00 +0000, day: 08, week: 46
INFO: tempDate: 2015-11-14 22:00:00 +0000, day: 15, week: 47
INFO: tempDate: 2015-11-21 22:00:00 +0000, day: 22, week: 48
INFO: tempDate: 2015-11-28 22:00:00 +0000, day: 29, week: 49
INFO: tempDate: 2015-12-05 22:00:00 +0000, day: 06, week: 50
INFO: tempDate: 2015-12-12 22:00:00 +0000, day: 13, week: 51
INFO: tempDate: 2015-12-19 22:00:00 +0000, day: 20, week: 52
INFO: tempDate: 2015-12-26 22:00:00 +0000, day: 27, week: 53
INFO: tempDate: 2015-12-26 22:00:00 +0000, day: 27, week: 1
INFO: tempDate: 2016-01-02 22:00:00 +0000, day: 03, week: 2
INFO: tempDate: 2016-01-09 22:00:00 +0000, day: 10, week: 3
INFO: tempDate: 2016-01-16 22:00:00 +0000, day: 17, week: 4
INFO: tempDate: 2016-01-23 22:00:00 +0000, day: 24, week: 5
and as you can see, the week 53 from 2015 has the same day as the week 1 from 2016 (This site tells me that there are 53 weeks in 2015).
Actually, the week 1 from 2016 starts from 04.01.2016.
Also, notice the dateWithString:formatString: gives me the previous day of the first day of the week. Why is that? I can simply use dateByAddingDays:1 but I don't know if it's hackish and the problem should be solved somewhere else.
I tried using NSDateComponents as #DarkDust mentioned, to no avail. So this:
for (NSInteger week = 1; week <= 5; week++) {
NSDate *tempDate = [NSDate dateWithString:[NSString stringWithFormat:#"2016-%d", (int)week] formatString:#"Y-w"];
NSDateComponents *dateComponents = [NSDateComponents new];
dateComponents.year = 2016;
dateComponents.weekOfYear = week;
NSLog(#"INFO: tempDate: %#, day: %.2d, week: %d = %#", tempDate, (int)[tempDate day], (int)week, [calendar dateFromComponents:dateComponents]);
}
gives me this:
INFO: tempDate: 2015-12-26 22:00:00 +0000, day: 27, week: 1 = 2015-12-31 22:00:00 +0000
INFO: tempDate: 2016-01-02 22:00:00 +0000, day: 03, week: 2 = 2015-12-31 22:00:00 +0000
INFO: tempDate: 2016-01-09 22:00:00 +0000, day: 10, week: 3 = 2015-12-31 22:00:00 +0000
INFO: tempDate: 2016-01-16 22:00:00 +0000, day: 17, week: 4 = 2015-12-31 22:00:00 +0000
INFO: tempDate: 2016-01-23 22:00:00 +0000, day: 24, week: 5 = 2015-12-31 22:00:00 +0000
Here is the DateTools' dateWithString:formatString: implementation:
+ (NSDate *)dateWithString:(NSString *)dateString formatString:(NSString *)formatString {
return [self dateWithString:dateString formatString:formatString timeZone:[NSTimeZone systemTimeZone]];
}
+ (NSDate *)dateWithString:(NSString *)dateString formatString:(NSString *)formatString timeZone:(NSTimeZone *)timeZone {
static NSDateFormatter *parser = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
parser = [[NSDateFormatter alloc] init];
});
parser.dateStyle = NSDateFormatterNoStyle;
parser.timeStyle = NSDateFormatterNoStyle;
parser.timeZone = timeZone;
parser.dateFormat = formatString;
return [parser dateFromString:dateString];
}
As for the duplicate report:
The top 3 are wrong, 2 of them with downvotes, and they don't even do what I need at all.
This is a bad idea what you are doing. You must understand a date is a time stamp which can be interpreted differently depending on the time zone and the calendar you are using. As it was already mentioned in comments you should use date components for your solution. Note that printing out the date may use a different format and the result may not be expected.
Next a first weekday in a year depends on definition. If I remember correctly some standards (or all) will treat the first week of the year depending on what day of week is the first day. In other words if 1.1 is sunday then the first week of the year is in december but if it is tuesday then it is in january.
So if you want to find the beginning of the first monday of the given year the code should look something like this (I did not test it):
+ (NSDate *)firstWeekInYear:(NSInteger)year {
NSCalendar *calendar = [NSCalendar autoupdatingCurrentCalendar];
NSDate *toReturn = nil;
NSDateComponents *components = [[NSDateComponents alloc] init];
components.year = year;
NSDate *beginningOfTheYear = [calendar dateFromComponents:components];
NSInteger day = [calendar component:NSCalendarUnitWeekday fromDate:beginningOfTheYear];
NSInteger daysToAdd = (8-day)%7;
toReturn = [calendar dateByAddingUnit:NSCalendarUnitDay value:daysToAdd toDate:beginningOfTheYear options:kNilOptions];
return toReturn;
}
So you need to choose the calendar, create date components with a target year, get the date from those components with the calendar to get the beginning of the year. Then find out what weekday that is and increase such a number of days so the result is the beginning of the first monday in a year.
I finally figured it out. #Matic's solution doesn't work in iOS 7 and it's hard to understand, so I managed to find a simpler solution that works on iOS 7 too:
+ (NSDate *)getFirstDayInWeek:(NSInteger)week ofYear:(NSInteger)year {
/* create the calendar only once */
static NSCalendar *calendar = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
calendar.firstWeekday = 2;
calendar.minimumDaysInFirstWeek = 4;
});
NSDateComponents *components = [NSDateComponents new]; // create an empty date components object
components.year = year;
components.weekOfYear = week; // set the number of the week in the year
components.weekday = calendar.firstWeekday; // important! set the result date's day of week
return [calendar dateFromComponents:components];
}

How to get valid quarter count instead of NSDateComponents.quarter is returning 0

NSDateComponents.quarter is returning 0 instead of valid quarter count.
I googled and it is said it is a bug for apple found in 2012. However, now it is 2015 and iOS 8.3, bug still exists.
What I need is the quarter count from firstDate to lastDate
for example:
unitFlags = NSQuarterCalendarUnit;
(lldb) po firstDate
2009-12-31 16:00:00 +0000
(lldb) po lastDate
2013-09-30 16:00:00 +0000
(lldb) po [gregorian components:unitFlags fromDate:firstDate toDate:lastDate options:0];
<NSDateComponents: 0x170158b50>
Quarter: 0

Can not format pubDate to NSDate iOS

I can not figure out why NSDate continues to throw nil.
NSString * copyString = [[self.parseResults objectAtIndex:indexPath.row]objectForKey:#"date"];
NSDateFormatter *df = [[[NSDateFormatter alloc] init] autorelease];
[df setDateFormat:#"EEE, dd MMM yyyy HH:mm:ss zzz"];
NSDate *date = [df dateFromString:copyString];
NSLog(#"%#", copyString);
NSLog(#"%#",date);
Did I set the date format set properly?
Output from copyString
2014-01-24 11:17:25.893 Events[32755:70b] Wed, 31 Dec 1969 16:00:00
PST
2014-01-24 11:17:25.895 Events[32755:70b] Fri, 24 Jan 2014 20:00:00
PST
2014-01-24 11:17:25.896 Events[32755:70b] Sat, 25 Jan 2014 10:00:00
PST
2014-01-24 11:17:25.897 Events[32755:70b] Mon, 27 Jan 2014 10:00:00
PST
2014-01-24 11:17:25.899 Events[32755:70b] Mon, 27 Jan 2014 12:15:00
PST
2014-01-24 11:17:25.900 Events[32755:70b] Mon, 27 Jan 2014 19:00:00
PST
Output from date
2014-01-24 11:22:24.707 Events[32827:70b] (null)
2014-01-24 11:22:24.709 Events[32827:70b] (null)
2014-01-24 11:22:24.710 Events[32827:70b] (null)
2014-01-24 11:22:24.712 Events[32827:70b] (null)
2014-01-24 11:22:24.713 Events[32827:70b] (null)
2014-01-24 11:22:24.714 Events[32827:70b] (null)

Joining Multiple Dataframes with Pandas with overlapping Column Names?

I have multiple (more than 2) dataframes I would like to merge. They all share the same value column:
In [431]: [x.head() for x in data]
Out[431]:
[ AvgStatisticData
DateTime
2012-10-14 14:00:00 39.335996
2012-10-14 15:00:00 40.210110
2012-10-14 16:00:00 48.282816
2012-10-14 17:00:00 40.593039
2012-10-14 18:00:00 40.952014,
AvgStatisticData
DateTime
2012-10-14 14:00:00 47.854712
2012-10-14 15:00:00 55.041512
2012-10-14 16:00:00 55.488026
2012-10-14 17:00:00 51.688483
2012-10-14 18:00:00 57.916672,
AvgStatisticData
DateTime
2012-10-14 14:00:00 54.171233
2012-10-14 15:00:00 48.718387
2012-10-14 16:00:00 59.978616
2012-10-14 17:00:00 50.984514
2012-10-14 18:00:00 54.924745,
AvgStatisticData
DateTime
2012-10-14 14:00:00 65.813114
2012-10-14 15:00:00 71.397868
2012-10-14 16:00:00 76.213973
2012-10-14 17:00:00 72.729002
2012-10-14 18:00:00 73.196415,
....etc
I read that join can handle multiple dataframes, however I get:
In [432]: data[0].join(data[1:])
...
Exception: Indexes have overlapping values: ['AvgStatisticData']
I have tried passing rsuffix=["%i" % (i) for i in range(len(data))] to join and still get the same error. I can workaround this by building my data list in a way where the column names don't overlap, but maybe there is a better way?
In [65]: pd.concat(data, axis=1)
Out[65]:
AvgStatisticData AvgStatisticData AvgStatisticData AvgStatisticData
2012-10-14 14:00:00 39.335996 47.854712 54.171233 65.813114
2012-10-14 15:00:00 40.210110 55.041512 48.718387 71.397868
2012-10-14 16:00:00 48.282816 55.488026 59.978616 76.213973
2012-10-14 17:00:00 40.593039 51.688483 50.984514 72.729002
2012-10-14 18:00:00 40.952014 57.916672 54.924745 73.196415
I would try pandas.merge using the suffixes= option.
import pandas as pd
import datetime as dt
df_1 = pd.DataFrame({'x' : [dt.datetime(2012,10,21) + dt.timedelta(n) for n in range(10)], 'y' : range(10)})
df_2 = pd.DataFrame({'x' : [dt.datetime(2012,10,21) + dt.timedelta(n) for n in range(10)], 'y' : range(10)})
df = pd.merge(df_1, df_2, on='x', suffixes=['_1', '_2'])
I am interested to see if the experts have a more algorithmic approach to merge a list of data frames.

Resources