So I have some AppleScriptObjC code that does some things with dates. One of the first things it does is convert todays date into an NSDate object.
set nowDate to current application's NSDate's |date|()
I'd like to be able to set nowDate to any date I choose. From everything I have read, up until 10.11 this was a very complex process. But in 10.11 it supposedly got easier. I couldn't actually find any examples on how it was easier.
What I'd really like is to be able to say
set aDate to current date
set day of aDate to "15"
set month of aDate to "5"
set year of aDate to "2020"
set hours of aDate to "13"
set minutes of aDate to "00"
set seconds of aDate to "00"
set nowDate to NSDate's aDate --or something simple like that
I also found this function that looks to be able to set a date to any date you would like, but I have not idea how to convert this into useful ASOBJC code (I fumbled around a bit with it, but got nowhere):
- (NSDate *)dateWithEra:(NSInteger)eraValue
year:(NSInteger)yearValue
month:(NSInteger)monthValue
day:(NSInteger)dayValue
hour:(NSInteger)hourValue
minute:(NSInteger)minuteValue
second:(NSInteger)secondValue
nanosecond:(NSInteger)nanosecondValue;
Bonus question... what is the integer value for the era we are in?
Although AppleScriptObjC will easily convert an NSDate to an AppleScript date, there isn't anything quite that simple for going the other way.
There is something quite simple: AppleScript date is implicitly bridged to NSDate when being used as a parameter so you can convert it easily with
use AppleScript version "2.5"
use framework "Foundation"
use scripting additions
set currentDate to current date
set cocoaDate to current application's NSDate's dateWithTimeInterval:0 sinceDate:currentDate
log cocoaDate
Although AppleScriptObjC will easily coerce an NSDate to an AppleScript date, there isn't anything quite that simple for going the other way. Cocoa has a ton of options for dates, so you will need to use a few statements to define what you want.
The conversion for your Objective-C method would be something like (don't forget the pipes around AppleScript terms):
use framework "Foundation"
use scripting additions
tell (current date) to set {theDay, theMonth, theYear, theHours, theMinutes, theSeconds} to {its day, its month as integer, its year, its hours, its minutes, its seconds}
set theCalendar to current application's NSCalendar's currentCalendar
theCalendar's dateWithEra:1 |year|:theYear |month|:theMonth |day|:theDay hour:theHours minute:theMinutes |second|:theSeconds nanosecond:0
You could also use NSDateFormatter to convert from an ISO date string:
tell ((current date) as «class isot» as string) to set dateString to it
set formatter to current application's NSDateFormatter's alloc's init
formatter's setDateFormat:"yyyy-MM-dd'T'HH:mm:ss"
# formatter's setLocale:(current application's NSLocale's alloc's initWithLocaleIdentifier:"en_US_POSIX")
formatter's dateFromString:dateString
For your bonus question, it depends on the calendar used, but for the Gregorian Calendar there are two eras, BCE/BC and CE/AD. From the Apple's Date and Time Guide, if you are using negative years for BCE, the era would be 0, otherwise it would be 1.
Related
i am currently working with VB6, and i have this value of date that is like this:
2022-02-26T12:06:10+02:00
I followed this url too
VB6: How to remove the Time part from Date type
but doesnt work especially the last one still shows the date as
2022-02-26T12:06:10+02:00
This is my code
Dim tdate As String
tdate = format$("2022-02-26T12:06:10+02:00" , "m/d/yyyy")
and the output is still 2022-02-26T12:06:10+02:00
Your input is a string in ISO8601 format. As its a string in a fixed format the easiest way is to just chop off the first 10 characters.
isoDateTimeString = "2022-02-26T12:06:10+02:00"
To get the date part as another string:
Dim dateAsString As String
dateAsString = Left$(isoDateTimeString, 10)
'// for 2022-02-26
Or to get it as a Date type:
Dim dateAsDateType As Date
dateAsDateType = CDate(Left$(isoDateTimeString, 10))
'// for 26/02/2022 (or whatever your locale format is)
In VB6 I've always found that the easiest way to deal with time/date values is to cast them as a Double (simply declare a variable as type Double, then assign the value from whatever source). Then, simply deal with either the integer part (days) or the fractional part (fractional days). For example, seconds are just TimeStamp/86400.0, etc. When a variable is declared as Date, it's actually stored as a Double, so I just use that as my basic TimeStamp type. VB is pretty good about re-formatting into a time/date string when printing, and it makes time-based calculations really straight-forward.
I have a calendar object that lists a number of object events. Each event contains a start_date. So when I call
event.start_date it gives me "8/6/2017 3:00pm"
I want to be able to find all the events with today's date. I'm using Chronic. So
Chronic.parse('today') would give me "8/6/2017 00:00:00" or something like it
I'm not using Rails just Ruby. Thus, I don't have all the special methods that come with Rails to help me with this.
If I enter a specific date I could find the events with that specific date by using
event.start_date.starts_with?("8/6/2017")
but I haven't figured out how to do it with today's date.
Any help would be appreciated.
time = Chronic.parse('today')
target_date = Chronic.parse('8/6/2017').to_date
puts time.to_date == target_date
Time class (what Chronic returns) holds datetimes. Date only holds dates. If you convert Time to Date, you discard the time-of-day information, and then you can compare just the date itself.
Note that Date.today is the same thing as Chronic.parse('today').to_date (and same as Time.now.to_date). Also note that Time class doesn't have #to_date unless you require 'time', but Chronic does it for you.
I'm trying to get the long time format in Windows (like "hh:mm:ss tt"). I can get the short time format like this:
GetLocaleInfoEx(NULL, LOCALE_STIMEFORMAT, format, 100);
I can't seem to find a constant for LOCALE_LTIMEFORMAT or anything like that. I can get the short time, short date and long date, but how can I query the current user's long time format?
As far as I can tell, windows defines the 'long' time format by LOCALE_STIMEFORMAT (set to something like "hh:mm:ss"), and the short time as LOCALE_SSHORTTIME (which, according to MSDN, is valid for Windows 7 and later).
Does that correspond to your findings, i.e. does it match the user preference in the Region and Language Control Panel item?
For the t specifier, if it is not included into the locale format, then either you are left with always using a custom format (like gbjbaanb said), or perhaps examining the format string for the presence of t or tt, and if absent adding it yourself (though, this might lead to odd results for cultures expecting the tt before the general time, for instance). This should not be necessary though, as the time format used by the locale is responsible for yielding time-strings that make sense (distinguishing between AM and PM, for instance).
What you are looking for is already included in LOCALE_STIMEFORMAT. Sample code:
wchar_t format[80]; // 80 is always enough
int ret = GetLocaleInfoEx(
LOCALE_NAME_USER_DEFAULT,
LOCALE_STIMEFORMAT,
format,
sizeof(format) / sizeof(*format));
if (ret == 0) die(GetLastError());
std::wcout << format << std::endl;
Output on my machine (I live in the USA):
h:mm:ss tt
The "tt" part will be absent for any culture or locale customization that does not display the AM/PM designator.
The LOCALE_STIMEFORMAT is the long time format. To get the short time format you can use LOCALE_SSHORTTIME starting with Windows 7 or cut off the seconds.
To confirm this simply change the long time format in your Control Panel / Region and Language settings.
Try using it with the LOCALE_S1159 and LOCALE_2359 constants which return the text for the AM/PM designators.
I think the issue is that time format is a time format, down to the second. You have to format it yourself if you want AM/PM just like you do with daylight savings time or timezone indicators.
I have an NSTextField with NSDateFormatter. The formatter accepts 'mm/dd/yy'.
Is it possible to complete the date automatically? So the user can type 'mm' and the formatter completes the current month and year.
Any particular reason you don't want to use an NSDatePicker? (It does require 10.4 and later, but that's less of an issue these days)...
No.
You are going to need some logic that detects when "mm" is present in the text field and then get the current date from NSDate and then pass that into the date formatter to get the string and then display it in the text field.
You could also investigate the various delegate methods available to NSTextField. If my memory serves me right, there is didBeginEditing (which is inherited from NSControlTextEditingDelegate, check that class reference). However, I'm not sure if that fires every time you input a new character...though it may. In which case it'd be a case of assigning a delegate that checks the NSText string and does a little comparison.
Is there a way to represent dates like 12/25 without year information? I'm thinking of just using an array of [month, year] unless there is a better way.
You could use the Date class and hard set the year to a leap year (so that you could represent 2/29 if you wanted). This would be convenient if you needed to perform 'distance' calculations between two dates (assuming that you didn't need to wrap across year boundaries and that you didn't care about the off-by-one day answers you'd get when crossing 2/29 incorrectly for some years).
It might also be convenient because you could use #strftime to display the date as (for example) "Mar-3" if you wanted.
Depending on the usage, though, I think I would probably represent them explicitly, either in a paired array or something like YearlessDate = Struct.new(:month,:day). That way you're not tempted to make mistakes like those mentioned above.
However, I've never had a date that wasn't actually associated with a year. Assuming this is the case for you, then #SeanHill's answer is best: keep the year info but don't display it to the user when it's not appropriate.
You would use the strftime function from the Time class.
time = Time.now
time.strftime("%m/%d")
While #Phrogz answer makes perfect sense, it has a downside:
YearlessDate = Struct.new(:month,:day)
yearless_date = YearlessDate.new(5, 8)
This interface is prone to MM, DD versus DD, MM confusion.
You might want to use Date instead and consider the year 0 as "yearless date" (provided you're not a historian dealing with real dates around bc/ad of course).
The year 0 is a leap year and therefore accommodates every possible day/month duple:
Date.parse("0000-02-29").leap? #=> true
If you want to make this convention air tight, just define your own class around it, here's a minimalistic example:
class YearlessDate < Date
private :year
end
The most "correct" way to represent a date without a year is as a Fixnum between 001 and 365. You can do comparisons on them without having to turn it into a date, and can easily create a date for a given year as needed using Date.ordinal