Rails string to DOB year - ruby-on-rails

I'm currently storing strings formatted like "01/01/1989" (client side validation) for the bday field.
I want to parse out the year and store it as a variable, like this:
#bdayyear = current_user.bday.year
I want that to bring back "1989"
How would I go about doing that?

Just do using #strftime and ::strptime :
s = "01/01/1989"
current_user.bday.strptime(s, "%d/%m/%Y").strftime("%Y")
# => "1989"

Convert it into a DateTime object and you can call year on it
>> DateTime.parse("01/01/1989").year
=> 1989

If the format is always consistent the why not just use the string
"01/01/1989".slice(-4..-1)
"01/01/1989"[-4..-1]
Or
"01/01/1989".split(/\W/).pop
These will all return "1989" without converting it to a date

Related

Convert active support timezone object in string back to object in rails

How can I convert the active support time object converted to string back to object, In other words, how can I find the active support object from its string?
Example:
a = ActiveSupport::TimeZone.all.first =
#<ActiveSupport::TimeZone:0x007f8c45bc1848 #name="American Samoa",
#tzinfo=#<TZInfo::TimezoneProxy: Pacific/Pago_Pago>, #utc_offset=nil>
If I convert this object to a string using to_s, I get "(GMT-11:00) American Samoa" .
How can i find the object if i have "(GMT-11:00) American Samoa".
This will eliminate everything between the first pair of parentheses and grab the remaining string:
a = ActiveSupport::TimeZone.all.first.to_s.match(/\(.*?\) (.*)/)[1]
...and with that you can find the ActiveSupport::Timezone object:
ActiveSupport::Timezone[a]
# let
timezone_string = '(GMT-11:00) American Samoa'
# let's capture the "American Samoa" substring from above (as an example)
matches = timezone_string.match /\(GMT.*?\) (.*)/
timezone_name = matches[1]
# then we look up the corresponding Timezone object using the "American Samoa" timezone_name
timezone = ActiveSupport::TimeZone[timezone_name]
Thank you for the answers i did try them and it works.
I also tried this
tz_value = business_timezone.split(')').second.strip
which gives me the name and i am finding the object using
ActiveSupport::TimeZone[tz_value].

Converting a string into a date Ruby on Rails

I'm attempting to convert a string date into a date that can be stored in the database. These are my attempts:
params[:event][:start_date] = '03-21-2016'
DateTime.strptime(params[:event][:start_date], '%Y-%m-%dT%H:%M:%S%z')
or
DateTime.strptime(params[:event][:start_date], '%m-%d-%Y')
However I keep getting an invalid date error. I'm not sure what I'm doing wrong.
One way to do it would be this:
date_string = '03-21-2016'
month, day, year = date_string.split('-').map(&:to_i)
DateTime.new(year, month, day)
You need to understand what each fragment (eg %Y) in the format string ('%Y-%m-%dT%H:%M:%S%z') means: read this.
http://apidock.com/rails/ActiveSupport/TimeWithZone/strftime
Once you know this, you can tailor a format string to the date string you have, or expect to get: in this case, "%m-%d-%Y".
When debugging create a new, basic and simple, version of the code and test that.
require 'date'
params = '03-21-2016'
DateTime.strptime(params, '%m-%d-%Y') # => #<DateTime: 2016-03-21T00:00:00+00:00 ((2457469j,0s,0n),+0s,2299161j)>
Note the order for the format: '%m-%d-%Y', which works. That's the problem with your first attempt, where you tried to use%Y-%m-%d. There is NO month21or day2016`.
Your second attempt is valid but your question makes it appear it doesn't work. You need to be more careful with your testing:
params = {event:{start_date:'03-21-2016'}}
DateTime.strptime(params[:event][:start_date], '%m-%d-%Y') # => #<DateTime: 2016-03-21T00:00:00+00:00 ((2457469j,0s,0n),+0s,2299161j)>

Deserialize joda time from string in grails?

I had a LocalTime field (using Joda Time) in Grails domain class.
Class WorkDone{
LocalTime duration
}
Now I have altered this field to String (with Text constraint) so that it can support duration larger than 24 hrs.
String duration
The problem is there is already some data in database. And I want to sanitize that data through database migrations in Grails. I am using Postgres which saves LocalTime as Bytea (binary data).
When I call WorkDone.duration it returns me a String of the form:
\xaced0005737200176f72672e6a6f64612e74696d652e4c6f63616c54696d65fffff44abbf29def0200024a000c694c6f63616c4d696c6c69734c000b694368726f6e6f6c6f677974001a4c6f72672f6a6f64612f74696d652f4368726f6e6f6c6f67793b78700000000000000000737200276f72672e6a6f64612e74696d652e6368726f6e6f2e49534f4368726f6e6f6c6f67792453747562a9c811667137502703000078707372001f6f72672e6a6f64612e74696d652e4461746554696d655a6f6e652453747562a62f019a7c321ae30300007870770500035554437878
How can I extract time from this string?
Your data is scaped in bytea Hex format, (starts with \x) take a look at PostgreSQL docs
http://www.postgresql.org/docs/current/static/datatype-binary.html
You have to unescape it before read as ObjectInputStream ang get the LocalTime object, unescape it and then try again as Raphael suggest.
You should have done a data-migration before changing your Data-type to String.
Here is what you should do.
1. Change the Data-type of the field back to LocalTime.
2. Create a new field with String Date.
3. Write a script that would get all date in LocalTime and convert it to String and save it in new field.
4. Once you have your data migrated, delete the old field and then rename your new field to duration.
I ended up doing the following -
grailsChange{
change{
sql.eachRow("Select id,duration from work_done"){
def wdId = it.id
def durationObj = (LocalTime)(new ObjectInputStream(new ByteArrayInputStream(it.duration))).readObject()
durationObj = durationObj.toString().substring(0,8)
WorkDone.executeUpdate("update WorkDone wd set wd.duration=:newDuration" +
"where wd.id=:wdId",
[newDuration:durationObj ,wdId:wdId ])
}
}

Delphi & Absolute database : Delete Query

Why is it that my query does not work ?
Form1.ABSQuery1.Close;
Form1.ABSQuery1.SQL.Clear;
Form1.ABSQuery1.SQL.Text:='DELETE FROM LOG WHERE status = ''YES'' and DATE BETWEEN :d1 and :d2';
Form1.ABSQuery1.Params.ParamByName('d1').Value :=cxDateEdit1.Date;
Form1.ABSQuery1.Params.ParamByName('d2').Value :=cxDateEdit2.Date;
Form1.ABSQuery1.ExecSQL;
Form1.ABSTable1.Refresh;
I get this error :
You should be using AsDateTime in your Params setting code.
Form1.ABSQuery1.SQL.Text:='DELETE FROM LOG WHERE status = ''YES'' and DATE BETWEEN :d1 and :d2';
Form1.ABSQuery1.Params.ParamByName('d1').AsDateTime :=cxDateEdit1.Date;
Form1.ABSQuery1.Params.ParamByName('d2').AsDateTime :=cxDateEdit2.Date;
Form1.ABSQuery1.ExecSQL;
Using Value converts the cxDateEdit1.Date to a generic string format for assignment, and that doesn't properly convert it to the YYYY-MM-DD format that most databases (including ABS) expect. Properly using AsDateTime allows the database driver/component to convert to the specific date format the DBMS uses.
Also, is your database field really named DATE? Date is usually a reserved word or function name in most DBMS, and if it is it usually needs to be quoted.
Form1.ABSQuery1.Params.ParamByName('d1').DataType := ftDateTime;
Form1.ABSQuery1.Params.ParamByName('d1').Value :=cxDateEdit1.Date;
You must explicitly specify the data type of the parameter to it had no such problem, and then convert to a string does not need to

Saving and Querying a Date in GORM Grails

I have a database table TableA, which has a column 'theDate' for which the datatype in the database is DATE.
When I save a java.util.Date to 'theDate' through GORM it appears to save just the date value when I look at the data in the table by just executing select * from TableA.
However, when I run a query such as:
select * from TableA where theDate = :myDate
No results are found, but if I run something like;
select * from TableA where theDate <= :myDate
I do get results.
So it's like the Time is relevant.
My question is how do I save a Date and query for a Date ignoring the Time completely and just matching on an exact Date only?
Thanks.
note: I have also tried using sql.Date and util.Calendar but to no success.
clearTime()
You can use clearTime() before saving and before comparing to zero out the time fields:
// zero the time when saving
new MyDomain(theDate: new Date().clearTime()).save()
// zero the target time before comparing
def now = new Date().clearTime()
MyDomain.findAll('SELECT * FROM MyDomain WHERE theDate = :myDate', [myDate: now])
joda-time plugin
An alternative would be to install the joda-time plugin and use the LocalDate type (which only holds date information, no times) instead of Date. For what it's worth, I don't think I've worked on a project with dates without using the Joda plugin. It's completely worth it.
If you have date saved without clearing you could retrieve it using range, as Jordan H. wrote but in more simple way.
def getResults(Date date) {
def from = date.clearTime()
def to = from + 1
def results = MyDomain.findAll("from MyDomain where dateCreated between :start and :stop" ,[start:from,stop:to])
}
Your question may be a duplicate. See Convert datetime in to date. But if anyone has more recent information, that would be great.
If that doesn't help, you can hack it the way I might, with a BETWEEN restriction, e.g.
def today = new Date()
def ymdFmt = new java.text.SimpleDateFormat("yyyy-MM-dd")
def dateYmd = ymdFmt.format(today)
def dateTimeFormat = new java.text.SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
def startDate = dateTimeFormat.parse("${dateYmd} 00:00:00");
def endDate = dateTimeFormat.parse("${dateYmd} 23:59:59");
MyDomain.findAll("from MyDomain where dateCreated between ? and ?", [startDate, endDate])
It's definitely not pretty, but it may get you where you're going.
I figured it out.
I used DateGroovyMethods.clearTime to clear the time value before saving.
You can use the DB type date not datetime , in the filed type

Resources