NSDateFormatter "w" - objective-c

In my app, I used "w" to format date:
With "w", does a new week start on Sundays?
The date is local right?

NSDateFormatter will use your location settings (See NSLocal).
So If canadian is your local and canadian calendars starts on Saturday this is your week.

For your question about the week element,
The following is from HERE, your NSDateFormatter uses the ISO Standard.
Week date is an alternative date representation used in many
commercial and industrial applications. It is: YYYY-Www-D
where YYYY is the Year in the Gregorian calendar, ww is the week of
the year between 01 (the first week) and 52 or 53 (the last week), and
D is the day in the week between 1 (Monday) and 7 (Sunday).
Example: 2003-W14-2 represents the second day of the fourteenth week
of 2003.
This means that for the Gregorian calendar, the weeks start on Mondays.
In additions to PascalTurbo's post, if you need to, you can explicitly set set the timezone for your date formatter like the following example:
NSDateFormatter *dateFormatter.timeZone = [NSTimeZone timeZoneWithAbbreviation:#"GMT"];

Related

Postgresql extract week

Why when I run
select (EXTRACT(WEEK FROM current_date)::int )
The output is 6 - why?
Today is 2016-02-14 which is the 8th week since the start of this year.
Am I getting this result wrong?
I'm looking for a function which I give it date and it tells me what week of the year this date is.
The documentation is pretty clear on the calculation:
week
The number of the ISO 8601 week-numbering week of the year. By
definition, ISO weeks start on Mondays and the first week of a year
contains January 4 of that year. In other words, the first Thursday of
a year is in week 1 of that year.
In the ISO week-numbering system, it is possible for early-January
dates to be part of the 52nd or 53rd week of the previous year, and
for late-December dates to be part of the first week of the next year.
For example, 2005-01-01 is part of the 53rd week of year 2004, and
2006-01-01 is part of the 52nd week of year 2005, while 2012-12-31 is
part of the first week of 2013. It's recommended to use the isoyear
field together with week to get consistent results.
Weeks start on a Monday, so Sunday is the end of a week (and "today" is Sunday where I am and in most of the world at this particular time). Also, the first week depends on the when the year starts.

VB.NET DatetimePicker - Wrong week number

I have an issue with my vbnet extented datetime picker.
When the element pass to new year (2016), the week number displayed on the left is wrong.
I have a "datetimepicker" which is not the default component, it was downloaded here :
http://www.codeproject.com/Articles/17063/ExtendedDateTimePicker-control-with-week-numbers
I don't understand why the calendar pass from 53 to 2 and not 53 to 1.
Maybe one of you has the same error.
Thanks for your time.
I don't understand why the calendar pass from 53 to 2 and not 53 to 1
It is pretty much working as expected. The way it is counting weeks, those first 3 days of 2016 count as the first week of 2016.
Note that the control doesnt do anything calendar or display related. It is simply changing the display style of the calendar window provided by Windows. The code seen on the CP page is all there is and mainly it just sets a style flag to tell Windows to add the week numbers:
style = style | MCS_WEEKNUMBERS;
The MSDN entry for it indicates:
Week 1 is defined as the first week that contains at least four days.
Since Jan 1-3 is not 4 days, it would seem that there is either an error, a different calendar being used or MSDN is out of date.
From comments:
From what i understood, what's wrong is "date format". Maybe it's not a 8601
No, it is more than that: ISO8601 is a different calendar which neither Windows nor NET implements. Wikipedia notes:
The first week of a year is the week that contains the first Thursday of the year (and, hence, always contains 4 January). ISO week year numbering therefore slightly deviates from the Gregorian for some days close to 1 January.
This is what you see in the calendar drop down.
Alternative
But the ISO8601 Week Of Year is easy to calculate:
Start with the code for GetISOWeekOfYear() from my answer to a very similar question. You can use that to display the ISO8601 week of year for the selected date in a label or something next to the DTP.
Print the first and last week numbers for 2011 To 2021:
Dim cal As Calendar = CultureInfo.CurrentCulture.DateTimeFormat.Calendar
For n As Int32 = 2011 To 2017 '2021
dt = New DateTime(n, 12, 21)
Console.WriteLine(" ***** {0} *****", n)
For j = 0 To 3
Dim NetWk = cal.GetWeekOfYear(dt, CalendarWeekRule.FirstDay, firstD)
Console.WriteLine("Invariant Date: {0} ISO #:{1:00} NET #:{2:00}",
dt.ToString("MM/dd/yyyy"), GetISOWeekOfYear(dt), NetWk)
dt = dt.AddDays(7)
Next
Next
The result for 2015/2016 portion:
***** 2015 *****
Invariant Date: 12/21/2015 ISO #:52 NET #:52
Invariant Date: 12/28/2015 ISO #:53 NET #:53
Invariant Date: 01/04/2016 ISO #:01 NET #:02
Invariant Date: 01/11/2016 ISO #:02 NET #:03
***** 2016 *****
Invariant Date: 12/21/2016 ISO #:51 NET #:52
Invariant Date: 12/28/2016 ISO #:52 NET #:53
Invariant Date: 01/04/2017 ISO #:01 NET #:01
Invariant Date: 01/11/2017 ISO #:02 NET #:02
Unless you are willing to write your own control from scratch or license one which can be set to a different calendar (and has a definition for ISO8601), that may be the best you can do.
The Bottomline: The Week number is not wrong. It using a different calendar than you expect/want.
References:
Get or convert NET GetWeekOfYear() to ISO week
MSDN: Month Calendar Control Styles
DateTimePicker in Reference Source
The control is working fine.
When the year changes over the final few days of the year are in week 53 - but it's not a full week. Similarly the first few days of the year are in week 1, but the control takes the system's "first day of the week" setting to determine when week 2 begins - so it is possible for the first week of the year to have any where from 1 to 7 days in it.
This means that the image you've shown is showing Week 53 because you're in December and Week 2 because the 2nd week of January does start on the 4th.
If you navigate to January it would display week 1 for the row starting on December 28.
The bottom-line is that the first week in January only has 3 days in it.
This is just the normal and correct behaviour of this control.

Given an NSDate, find the last day of fourth prior month

I am trying to calculate an NSDate object based on the current date. If the current date is April 1st, 2015, I need to generate the date, December 31, 2014. If the current date is April 30th, 2015, I STILL need to generate the date, December 31, 2014. If however, it is May 1st, 2015, I need to generate January 31st, 2015. In other words, whatever month I am in, I need the date of the end of the month, from four months ago, regardless of where I am in the current month.
The code I have thus far is:
NSCalendar *theCalendar = [NSCalendar currentCalendar];
NSDateComponents *dayComponent = [[NSDateComponents alloc] init];
[dayComponent setDay:-90];
NSDate *nextDate = [theCalendar dateByAddingComponents:dayComponent toDate:[NSDate date] options:0];
NSLog(#"The date I am getting is: %#", nextDate);
The above code gives me the date value of exactly 90 days prior to the current date, but I need the date to always be the end of the month that is 4 months earlier.
As you've already discovered, you need a starting date and a calendar:
NSDate *startingDate = [NSDate date];
NSCalendar *calendar = [NSCalendar autoupdatingCurrentCalendar];
You'll need the components of the current date but only down to the current month, because you don't care about the specific day within the month:
NSDateComponents *components = [calendar
components:NSCalendarUnitEra | NSCalendarUnitYear | NSCalendarUnitMonth
fromDate:startingDate];
You say you want the last day of the fourth prior month. Since months have different numbers of days, the last day varies depending on the month. But all months have first days, and those first days are always numbered 1. So it's easiest to compute “the last day of the fourth prior month” by first going back three months:
components.month -= 3;
Then, go one day prior to that month:
components.day = -1;
Finally, you need to get clear in your head that an NSDate represents an instant in time, but a day (like “April 1st, 2015”) is an interval of time, starting and ending at specific instants. If you're going to represent a whole day using an NSDate, you're going to be storing one instant within that interval. You don't want to store the first or last instant (which will both be midnights); that causes problems for some days in some time zones. Instead, use noon as your instant:
components.hour = 12;
Now you're ready to ask the calendar for a new NSDate:
NSDate *lastDayOfFourthPriorMonth = [calendar dateFromComponents:components];
You want to get familiar with NSCalendar and NSDateComponents. If you read those two API documents, you will be able to assemble the answer.
Conceptually, you want to use NSCalendar components:fromDate: to get the components (day, month, year) of the current date.
You will then walk that month value back 4 months. Now if that wraps past January, you know you need to determine how much, so that you adjust and stay within months [1..12]. Further, you'll need to decrement the year at that point too.
Knowing the month, you can find the last day of that month through several means; the crudest of which is to maintain your own enum...but there's probably a better way using NSCalendar that will also account for February in leap years.
At the end, you can build the resultant date from the components you've assembled, using the NSCalendar method dateFromComponents:.
See #rob mayoff's excellent answer which is a more concrete realization of this theory and IMO, the correct answer.

nsdate format to last digit in year, then day of year

The following code will output this (current day is Jan 15, 2015):
2015015
I need it to output this:
5015
I want it in the format of yddd, where y is the last number in the year, and ddd is the day of the year. so January 1st, 2000 is 0001 and December 31st, 2007 is 7365.
NSDate *julianLabel = [NDDate date];
NSDateFormatter *julianFormatter = [[NSDateFormatter alloc] init];
[julianFormatter setDateFormat:#"yddd"];
self.julian.text = [julianFormatter stringFromDate:julianLabel];
Surely you could just use substringFromIndex on the string, something that should work for the next eight thousand years or so (a). In other words, something like:
self.julian.text = [[julianFormatter stringFromDate:julianLabel] substringFromIndex:3];
(a) It'll work as per your specification until we reach the year 10,000 but keep in mind you'll start getting duplicates in 2025. I'm assuming that's not a problem due to the detail provided.

NSDateFormatter show wrong year

im using xcode 4.5(4G182) with iOS 6. NSDateFormatter show wrong year in iOS 6, how to solve?
NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
[dateFormatter setDateFormat:#"YYYY-MM-dd"];
NSString *str = [dateFormatter stringFromDate:[NSDate date]];
NSLog(#"%# == %#",str,[[dateFormatter dateFromString:str] description]);
it print out "2012-09-14 == 2011-09-13 16:00:00 +0000"
YYYY is not the same as yyyy.
According to this page which the iOS Date format page references;
`y`: Year
`Y`: Year (in "Week of Year" based calendars). This year designation is used in
ISO year-week calendar as defined by ISO 8601, but can be used in
non-Gregorian based calendar systems where week date processing is desired.
May not always be the same value as calendar year.
The operative sentence being the last one. Use yyyyinstead.
Further details on how and why the year values may deviate when using YYYY:
The ISO week-numbering year starts at the first day (Monday) of week
01 and ends at the Sunday before the new ISO year (hence without
overlap or gap). It consists of 52 or 53 full weeks. The ISO
week-numbering year number deviates from the number of the traditional
Gregorian calendar year on a Friday, Saturday, and Sunday, or a
Saturday and Sunday, or just a Sunday, at the start of the traditional
Gregorian calendar year (which are at the end of the previous ISO
week-numbering year) and a Monday, Tuesday and Wednesday, or a Monday
and Tuesday, or just a Monday, at the end of the traditional Gregorian
calendar year (which are in week 01 of the next ISO week-numbering
year). For Thursdays, the ISO week-numbering year number is always
equal to the traditional Gregorian calendar year number.
Examples:
Monday 29 December 2008 is written "2009-W01-1"
Sunday 3 January 2010 is written "2009-W53-7"
From https://en.wikipedia.org/wiki/ISO_8601#Week_dates
(bold styling added)