I have two strings , which are each got from respective shell commands and are not uniformly formatted.
Two strings obtained are as follows:
Date : Tue Feb 28 16:23:20 2017 -0600
Executed at : Tue Feb 28 17:24:06 EST 2017
EDIT: I get the above mentioned dates , one through git log and other through cat and store both in variables
First date is got through and stored in X:
sh 'git log <file> | grep Date | head -n 1 > X '
Second date is got through below and stored in Y:
sh 'cat chef-policy-release.log | grep <file> | tail -n 1 | grep -o "Executed at.*" > Y'
Now I wanted to pick out just date and time among that and wanted to check if executed time is after the Date value or not ?
Similar to Rao's answer, but with a function to parse the string, no need for date format strings, and without creating un-needed Date instances:
class DateTest{
public static void main(String[] args) {
String logDateString = args[0];
String execDateString = args[1];
Date logDate = parseDate(logDateString);
Date execDate = parseDate(execDateString);
System.out.println(execDate > logDate);
}
static def parseDate(String rawString) {
String dateString = rawString.substring(rawString.indexOf(":") + 1).trim();
new Date(Date.parse(dateString));
}
}
Here you go.
def dateStr1 = 'Tue Feb 28 16:23:20 2017 -0600'
def dateStr2 = 'Tue Feb 28 17:24:06 EST 2017'
def pattern1 = "EEE MMM dd HH:mm:ss yyyy Z"
def pattern2 = "EEE MMM dd HH:mm:ss z yyyy"
def date = new Date().parse(pattern1, dateStr1)
def executeDate = new Date().parse(pattern2, dateStr2)
assert date < executeDate, 'Execute Date is earlier than the date'
You may quickly try it online (negative test)Demo
EDIT: Based on OP's comment to parse the string and extract the date
You could have applied #GreBeardedGeek's parsing logic.
//Closure to get the date parsed
def getDate = { delimiter, dateFormat, dateStr ->
def dt = dateStr.substring(dateStr.indexOf(delimiter) + 1).trim()
println dt
new Date().parse(dateFormat, dt)
}
def dateStr1 = 'Date : Tue Feb 28 16:23:20 2017 -0600'
def dateStr2 = 'Executed at : Tue Feb 28 17:24:06 EST 2017'
def pattern1 = "EEE MMM dd HH:mm:ss yyyy Z"
def pattern2 = "EEE MMM dd HH:mm:ss z yyyy"
def date = getDate(':', pattern1, dateStr1)
def executeDate = getDate(':', pattern2, dateStr2)
assert date < executeDate, 'Execute Date is earlier than the date'
Edit#2 can be more simplified to:
//Set / assign the two dates
def dateStr1 = 'Date : Tue Feb 28 16:23:20 2017 -0600'
def dateStr2 = 'Executed at : Tue Feb 28 17:24:06 EST 2017'
def getDate = { dateStr -> Date.parse(dateStr.substring(dateStr.indexOf(':') + 1).trim()) }
assert getDate(dateStr1) < getDate(dateStr2), 'Execute Date is earlier than the date'
Related
I have a Ruby variable containing Timestamp , I need to get Date and Time from it , I am able to get Date (but wrong) time is always 00:00 (note: li is a variable getting from a file)
li = 'Date: Wed, 25 Dec 2019 23:16:52 -0600'
date = li.delete("Date: ")
=> "Wd,25c2019231652-0600"
puts date
Wd,25c2019231652-0600
Date.parse(date).to_s
=> "2020-09-25"
Time.parse(date).to_s
=> "2020-09-25 00:00:00 +0530"
DateTime.parse(date).to_s
=> "2020-09-25T00:00:00+00:00"
DateTime.parse(date).strftime('%Y-%d-%m %H:%M:%S')
=> "2020-25-09 00:00:00"
I need to get correct date and Time (either in UTC or -0600)
li = 'Date: Wed, 25 Dec 2019 23:16:52 -0600'
require 'date'
Date.strptime(li, 'Date: %a, %d %b %Y %H:%M:%S %z')
#=> #<Date: 2019-12-25 ((2458843j,0s,0n),+0s,2299161j)>
See Date::strptime. Date-time formatting directives are given in the doc DateTime#strftime.
When I use the Simple Data Writer and save responses to a file where the time is:
Date: Thu, 09 Aug 2018 15:13:51 GMT
I want to post the current timing which is 11 something i.e., this time - 4.
How to change this?
If this Date: Thu, 09 Aug 2018 15:13:51 GMT is a part of your response and you need to change it on the fly you can do this using JSR223 PostProcessor and Groovy language.
The relevant code which will extract the date from the response, subtract 4 hours from it and replace the old date with the new date would be something like:
def response = prev.getResponseDataAsString()
log.info("Full response: " + response)
use(groovy.time.TimeCategory) {
def detectedDate = (response =~ "Date: (.+) GMT")[0][1]
Date oldDate = Date.parse("EE, dd MMM yyyy HH:mm:ss", detectedDate)
Date newDate = oldDate - 4.hour
log.info("Old date: " + oldDate)
log.info("New date: " + newDate)
response = response.replace(detectedDate, newDate.format("EE, dd MMM yyyy HH:mm:ss"))
prev.setResponseData(response, "UTF-8")
}
Demo:
More information:
Groovy Goodness: Working with Dates
Apache Groovy - Why and How You Should Use It
I have the following string in UTC format: "2017-03-30 21:25:09". I need to convert this to the "America/Los_Angeles" and "America/New_York" time zone.
I tried the following but it didn't work.
utc_time = Time.parse(to_datetime.to_s).utc
pacific_time = utc_time + Time.zone_offset("PDT")
I also tried using DateTime#strptime, but that didn't work either.
to_datetime = DateTime.strptime(my_time_string, "%y-%m-%d %H:%M:%S")
How can I change the string so that it refers to the different time zone?
Use the TZInfo gem.
require 'tzinfo'
# parse the UTC time
utcTime = Time.parse("2017-03-30 21:25:09 UTC")
puts utcTime # "2017-03-30 21:25:09 UTC"
# convert it to a time zone
tz = TZInfo::Timezone.get('America/New_York')
localTime = tz.utc_to_local(utcTime)
# you cannot just puts this localTime, because the abbrevation will be incorrect
# you can get format directly from here and get the correct abbreviation with %Z
localString = tz.strftime("%Y-%m-%d %H:%M:%S %Z", utc = utcTime)
puts localString # "2017-03-30 17:25:09 EDT"
# as of v1.2.3, you can get the offset correctly with %z
localString = tz.strftime("%Y-%m-%d %H:%M:%S %z", utc = utcTime)
puts localString # "2017-03-30 17:25:09 -04:00"
# for older versions of tzinfo, %z didn't work so you had to create the offset manually
offset = tz.period_for_utc(utcTime).utc_total_offset
hoursOffset = (offset / 3600.0).truncate
minutesOffset = (offset.abs / 60) % 60
offsetString = sprintf("%+03d:%02d", hoursOffset, minutesOffset)
puts offsetString # "-04:00"
ActiveSupport provides the in_time_zone helper method. For example, you can set the TimeZone manually, instead of using the operating system's time zone.
Time.zone = 'Hawaii' # => 'Hawaii'
DateTime.new(2000).in_time_zone # => Fri, 31 Dec 1999 14:00:00 HST -10:00
You can also pass in a TimeZone instance or string that identifies a TimeZone as an argument, and the conversion will be based on that zone instead of Time.zone.
DateTime.new(2000).in_time_zone('Alaska') # => Fri, 31 Dec 1999 15:00:00 AKST -09:00
More info is in "ActiveSupport::TimeWithZone".
This is how I solved it, thanks to https://stackoverflow.com/users/634824/matt-johnson .
Input => convert_date_from_utc('2017-03-20 22:29:26', 'America/New_York')
Output=> 2017-03-20T18:29:26-04:00
# convert utc date to other time_zone with offset
def convert_date_from_utc(date, time_zone)
utcTime = Time.parse(date)
tz = TZInfo::Timezone.get(time_zone)
local_time = tz.utc_to_local(utcTime).to_s[0..18].gsub!(' ','T')
offset = tz.period_for_utc(utcTime).utc_total_offset
hoursOffset = (offset / 3600.0).truncate
minutesOffset = (offset.abs / 60) % 60
offsetString = sprintf("%+03d:%02d", hoursOffset, minutesOffset)
local_time+offsetString
end
I have the string "Sat, 21 Nov 2015 19:20:48 EST\n\t\t\t" that I need convert to NSDate, but it gives me nil all the time.
I tried to clear the string by
dateString.stringByReplacingOccurrencesOfString("\"", withString: "", options: NSStringCompareOptions.LiteralSearch, range: nil)
result looks fine: Sat, 21 Nov 2015 19:20:48. Converting to NSDate = nil :(
Ok, I removed the noised characters manually and try to convert the string "Sat, 21 Nov 2015 19:20:48 EST" to NSDate. Nil again:
let dateString = "Sat, 21 Nov 2015 19:20:48 EST"
let formatter = NSDateFormatter()
formatter.locale = NSLocale(localeIdentifier: 'US_en')
formatter.dateFormat = 'yyyy-MM-dd'
print("date = \(date)")
//date = nil
What am I doing wrong?
Even if I use "formatter.timeZone = NSTimeZone(abbreviation: "EST")" still nil.
Answer to your first question:
You could use the following code to trim the unwanted whitespace and newlines from the string
var dateAsString = "Sat, 21 Nov 2015 19:20:48 EST\n\t\t"
dateAsString = dateAsString.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())
Answer to your second question:
Refer to the Date format symbols table in this link for list of all string formatting symbols.
You should be able to convert the specified date with this formatter,
let customDateFormatter = NSDateFormatter()
dayTimePeriodFormatter.dateFormat = "EEE, dd MMM yyyy HH:mm:ss zzz"
let date = dayTimePeriodFormatter.dateFromString(dateAsString) //"Sat, 21 Nov 2015 19:20:48 EST"
Simple question, but I can't find a good or definitive answer. What is the best and most efficient way to combine Ruby Date and Time objects (objects, not strings) into a single DateTime object?
I found this, but it's not as elegant you would hope:
d = Date.new(2012, 8, 29)
t = Time.now
dt = DateTime.new(d.year, d.month, d.day, t.hour, t.min, t.sec, t.zone)
By the way, the ruby Time object also stores a year, month, and day, so you would be throwing that away when you create the DateTime.
When using seconds_since_midnight, changes in daylight savings time can lead to unexpected results.
Time.zone = 'America/Chicago'
t = Time.zone.parse('07:00').seconds_since_midnight.seconds
d1 = Time.zone.parse('2016-11-06').to_date # Fall back
d2 = Time.zone.parse('2016-11-07').to_date # Normal day
d3 = Time.zone.parse('2017-03-12').to_date # Spring forward
d1 + t
#=> Sun, 06 Nov 2016 06:00:00 CST -06:00
d2 + t
#=> Mon, 07 Nov 2016 07:00:00 CST -06:00
d3 + t
#=> Sun, 12 Mar 2017 08:00:00 CDT -05:00
Here's an alternative, similar to #selva-raj's answer above, using string interpolation, strftime, and parse. %F is equal to %Y-%m-%d and %T is equal to %H:%M:%S.
Time.zone = 'America/Chicago'
t = Time.zone.parse('07:00')
d1 = Time.zone.parse('2016-11-06').to_date # Fall back
d2 = Time.zone.parse('2016-11-07').to_date # Normal day
d3 = Time.zone.parse('2017-03-12').to_date # Spring forward
Time.zone.parse("#{d1.strftime('%F')} #{t.strftime('%T')}")
#=> Sun, 06 Nov 2016 07:00:00 CST -06:00
Time.zone.parse("#{d2.strftime('%F')} #{t.strftime('%T')}")
#=> Sun, 07 Nov 2016 07:00:00 CST -06:00
Time.zone.parse("#{d3.strftime('%F')} #{t.strftime('%T')}")
#=> Sun, 12 Mar 2017 07:00:00 CDT -05:00
Simple:
Date.new(2015, 2, 10).to_datetime + Time.parse("16:30").seconds_since_midnight.seconds
# => Object: Tue, 10 Feb 2015 16:30:00 +0000
You gotta love Ruby!
If using Rails, try any of these:
d = Date.new(2014, 3, 1)
t = Time.parse("16:30")
dt = d + t.seconds_since_midnight.seconds
# => ActiveSupport::TimeWithZone
dt = (d + t.seconds_since_midnight.seconds).to_datetime
# => DateTime
dt = DateTime.new(d.year, d.month, d.day, t.hour, t.min, t.sec)
# => DateTime
If you are using Ruby on Rails, this works great.
I built a method to extend the DateTime class to combine a date and a time. It takes the zone from the date so that it does not end up an hour off with daylight savings time.
Also, for convenience, I like being able to pass in strings as well.
class DateTime
def self.combine(d, t)
# pass in a date and time or strings
d = Date.parse(d) if d.is_a? String
t = Time.zone.parse(t) if t.is_a? String
# + 12 hours to make sure we are in the right zone
# (eg. PST and PDT switch at 2am)
zone = (Time.zone.parse(d.strftime("%Y-%m-%d")) + 12.hours ).zone
new(d.year, d.month, d.day, t.hour, t.min, t.sec, zone)
end
end
So you can do:
DateTime.combine(3.weeks.ago, "9am")
or
DateTime.combine("2015-3-26", Time.current)
etc...
I found another way, I hope this is correct.
datetojoin=Time.parse(datetime).strftime("%Y-%m-%d")
timetojoin=Time.parse(time).strftime("%T")
joined_datetime = Time.parse(datetojoin +" "+ timetojoin).strftime("%F %T")
Any thoughts? Please share.