Ruby strftime - show quarter + year - ruby

I'd like to format a date with the quarter and year, e.g.
Q1 2018
Is there any way to do this using strftime or I18n.l? I can't see anything RE quarters in the docs.
I've been doing
month = datum.recorded_at.month - 1
quarter = (month / 3) + 1
"Q#{quarter} #{datum.recorded_at.strftime('%y')}"
But this is not a good approach because it can't easily be localised (e.g. some of our white label partners might want to format dates differently rather than using quarters)

It sounds like you already know how to calculate the quarter, but you're not sure how to organize your code to allow for flexible formatting without hardcoding a particular format that uses quarters.
What you need is for strftime to have a "formatting directive" for quarters (e.g. %q)
You could override strftime to add a new directive, but generally it's best to avoid overriding such things.
Instead I'd recommend defining your own formatting module that understands %q and piggybacks on strftime for everything else:
module MyDateFormatter
def self.format_date(date, format)
quarter = get_quarter(date)
date.strftime(format.gsub("%q", "Q#{quarter}"))
end
def self.get_quarter(date)
# Put whatever quarter calculation you want to use here
end
end
Clients who want to use quarters can have a format string that includes your special %q directive, whereas clients who don't want quarters can have a format string that doesn't use %q.

Related

What is a simple way in Ruby to show the date and time?

I would like something in Ruby roughly equivalent to time.asctime() in Python:
import time
print(time.asctime())
outputs:
Sun Sep 11 10:12:48 2022
I'd like to avoid having to use strftime and having to remember or look up the formats. Also, ideally I'd like both day of the week (e.g., Sun) and the UTC timezone difference (e.g., -0400), but I'd settle for just day of the week.
puts Time.now.asctime
outputs:
Sun Sep 11 10:24:46 2022
Simple String Output
Ruby supports lots of Time, Date, and DateTime objects and output formats. While I think the first answer is closer to the output format you want, the following is potentially simpler and possibly sufficient for many needs when just considering standard output or standard error:
p Time.now.to_s
#=> 2022-09-11 14:10:57 -0400
# using interpolation
p "Time: #{Time.now.to_s}"
#=> "Time: 2022-09-11 14:15:51 -0400"
Other Considerations
Note that if you want to use the results for any sort of comparison or calculation, you'll likely need to convert the result to one of the three object types described above. That's the main reason I mention them. Unless it's just printing to the screen, you should think about how you plan to use the result before deciding which of the objects will be most useful for you.

Convert date format, BMC Remedy/smart-it

Problem:
In a field called $Detailed Decription$ sometimes dateformat 08/09/2021 is enterd and this need to be converted to swedish format 2022-02-11
I'am going to use BMC Developer studio and make a filter but i cant find a fitting solution for it. Replacing it wont work (i think) becaus it need to have a value to replace it with.
Maby there can be a function that reads regex (\d{2})/(\d{1,2})/(\d{4}) but how can i convert it?
If it's sometimes - look at AR System User Preferencje form. Check certain user's locale and date time config.
Also is important where the data comes from. Could be a browser setting or java script mod.
1- Using Set fields action, copy the date value from Detailed Description to a Date/Time field (i.e. z1D_DateTime01).
2- Using Set fields action and Functions (MONTH, YEAR, DAY, HOUR, MINUTE, SECOND) you can parse the date/time and convert it to format you like.
Something like this:
SwedishDate = YEAR($z1D_DateTime01$) + "-" + MONTH($z1D_DateTime01$) + "-" + DAY($z1D_DateTime01$)
This will capture the parts of date and combine them with "-" in the middle and in the order you want.

ZEN : Allow multiple date formats in a dateText control and converting them to the YYYY-MM-DD

There is a finite list of date formats that users want to use to enter a date in a form. These formats include single digits for month and day and double digits for year. The field is represented by a dateText control.
How would one get to allow a dateText control to accept multiple date formats ? I see only 3 listed (https://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY=GZCP_forms_dateText), do those include using single digits for month and day ?
I tried to set the value of format = "#(myPageProperty.myValue)# " but I got a compilation error in Studio so that went nowhere. Has anyone ever been able to set the format value depending on the user input value?
I am guessing that the control input value must be converted to the YYYY-MM-DD before validation. I am open to calling a javascript function to do that but where would be the best place to put it?
for details see Class %ZEN.Component.dateText
setting format:
Property format As %ZEN.Datatype.string(MAXLEN = 3, **VALUELIST = ",MDY,DMY,YMD",** ZENEXPRESSION = 1)
you have exactly 3 formats or ""
Your guess on values is correct and documented:
/// The value of this control is always in the canonical form: YYYY-MM-DD
As this is one of the oldest components of ZEN your only chance to achieve
your way of operation is to create your own version inheriting from
Class %ZEN.Component.dateText and overloading the parts you want to change

Changing the timezone strings of date_lang.php

CodeIgniter stores timezones for its date class in
system/language/english/date_lang.php
I would like to change the strings in this file so that
$lang['UM12'] = '(UTC -12:00) Baker/Howland Island';
$lang['UM11'] = '(UTC -11:00) Samoa Time Zone, Niue';
would instead be
$lang['-12:00'] = '(UTC -12:00) Baker/Howland Island';
$lang['-11:00'] = '(UTC -11:00) Samoa Time Zone, Niue';
Is this possible at all?
Any change I make to the UM__ portion of one line makes it show as a blank on the dropdown. The remaining (unchanged) lines appear OK.
I have also tried to clone this file to application/language/english/ with similar bad results.
Any insights on this?
It looks like this would require hacks to the date_helper.php file which I am not willing to do.
Instead, the date class in CI has the timezones() function which allows you to convert from, for example, UM5 to -5. In that case one can wrap this function around the U__ value coming from the view/dropdown -- and then save it to DB as -5 or some other INT.
Since I want to show the user their selected timezone on that same dropdown, I am forced to have DB fields for the U__ and INT timezone formats. As far as I know, there is no CI function to convert from -5 to UM5.
So, for the user, I pull the U__ format into the view to autopopulate the dropdown.
For timezone conversions and such, I use the INT format.

Yearless Ruby dates?

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

Resources