I am working on an application in which I need to get the current year, month, and day. Is there a way to get this information in the pre block of a rule?
Can I get this data as a string or a number or both?
There are currently time functions documented on http://docs.kynetx.com/docs/Time but none of them seem to work for what I am trying to do.
Is there a way to set the timezone when getting this data?
I was able to do it using strftime which appears to be an undocumented feature so use with caution.
ruleset a60x518 {
meta {
name "date-test"
description <<
date-test
>>
author "Mike Grace"
logging on
}
rule testing {
select when pageview ".*"
pre {
retTime = time:strftime(time:now({"tz":"America/Denver"}), "%c");
month = time:strftime(time:now({"tz":"America/Denver"}), "%B");
year = time:strftime(time:now({"tz":"America/Denver"}), "%Y");
day = time:strftime(time:now({"tz":"America/Denver"}), "%d");
}
{
notify("time",retTime) with sticky = true;
notify("month",month) with sticky = true;
notify("year",year) with sticky = true;
notify("day",day) with sticky = true;
}
}
}
App run on example.com twice. Once with the timezone set to New York and onother time set to Denver
I used this site http://www.statoids.com/tus.html to get the correct strings to use for the timezone. I have no idea if they all work. I just found this site and tried a few and they worked so use with caution.
Perhaps the docs got reverted. For convenience, here is the documentation for strftime:
time:strftime()
Convert a datetime string to a different format
Usage
time:strftime(`<string>`,`<format>`)
Valid format arguments to strftime follow the POSIX strftime conventions.
Samples
time:strftime(xTime,”%F %T”) # 2010-10-06 18:15:24
time:strftime(xTime,”%F”) # 2010-10-06
time:strftime(xTime,”%T”) # 18:19:29
time:strftime(xTime,”%A %d %b %Y”) # Wednesday 06 Oct 2010
time:strftime(xTime,”%c”) # Oct 6, 2010 6:25:55 PM
The other time functions:
time:now()
Current datetime based upon user’s location data
Usage
time:now()
time:now({“tz” : <timezone>)
time:new()
Create a new RFC 3339 datetime string from a string (allows some flexibility in how the source string is formatted)
Usage
time:new() # Equivalent to time:now()
time:new(<string>)
Valid formats for the datetime source string can be found in ISO8601 (v2000).
time:add()
Add (or subtract) a specific number of time units to a source string
Usage
time:add(<string>,{<unit> : n})
Related
I'm using Google Ads API v11 to upload conversions and adjust conversions.
I send hundreds of conversions each day and want to start sending batch requests instead.
I've followed Google's documentation and I upload/ adjust conversions exactly the way they stated.
https://developers.google.com/google-ads/api/docs/conversions/upload-clicks
https://developers.google.com/google-ads/api/docs/conversions/upload-adjustments
I could not find any good explanation or example on how to send batch requests:
https://developers.google.com/google-ads/api/reference/rpc/v11/BatchJobService
Below is my code, an example of how I adjust hundreds of conversions.
An explanation of how to do so with batch requests would be very appreciated.
# Adjust the conversion value of an existing conversion, via Google Ads API
def adjust_offline_conversion(
client,
customer_id,
conversion_action_id,
gclid,
conversion_date_time,
adjustment_date_time,
restatement_value,
adjustment_type='RESTATEMENT'):
# Check that gclid is valid string else exit the function
if type(gclid) is not str:
return None
# Check if datetime or string, if string make as datetime
if type(conversion_date_time) is str:
conversion_date_time = datetime.strptime(conversion_date_time, '%Y-%m-%d %H:%M:%S')
# Add 1 day forward to conversion time to avoid this error (as explained by Google: "The Offline Conversion cannot happen before the ad click. Add 1-2 days to your conversion time in your upload, or check that the time zone is properly set.")
to_datetime_plus_one = conversion_date_time + timedelta(days=1)
# If time is bigger than now, set as now (it will be enough to avoid the original google error, but to avoid a new error since google does not support future dates that are bigger than now)
to_datetime_plus_one = to_datetime_plus_one if to_datetime_plus_one < datetime.utcnow() else datetime.utcnow()
# We must convert datetime back to string + add time zone suffix (+00:00 or -00:00 this is utc) **in order to work with google ads api**
adjusted_string_date = to_datetime_plus_one.strftime('%Y-%m-%d %H:%M:%S') + "+00:00"
conversion_adjustment_type_enum = client.enums.ConversionAdjustmentTypeEnum
# Determine the adjustment type.
conversion_adjustment_type = conversion_adjustment_type_enum[adjustment_type].value
# Associates conversion adjustments with the existing conversion action.
# The GCLID should have been uploaded before with a conversion
conversion_adjustment = client.get_type("ConversionAdjustment")
conversion_action_service = client.get_service("ConversionActionService")
conversion_adjustment.conversion_action = (
conversion_action_service.conversion_action_path(
customer_id, conversion_action_id
)
)
conversion_adjustment.adjustment_type = conversion_adjustment_type
conversion_adjustment.adjustment_date_time = adjustment_date_time.strftime('%Y-%m-%d %H:%M:%S') + "+00:00"
# Set the Gclid Date
conversion_adjustment.gclid_date_time_pair.gclid = gclid
conversion_adjustment.gclid_date_time_pair.conversion_date_time = adjusted_string_date
# Sets adjusted value for adjustment type RESTATEMENT.
if conversion_adjustment_type == conversion_adjustment_type_enum.RESTATEMENT.value:
conversion_adjustment.restatement_value.adjusted_value = float(restatement_value)
conversion_adjustment_upload_service = client.get_service("ConversionAdjustmentUploadService")
request = client.get_type("UploadConversionAdjustmentsRequest")
request.customer_id = customer_id
request.conversion_adjustments = [conversion_adjustment]
request.partial_failure = True
response = (
conversion_adjustment_upload_service.upload_conversion_adjustments(
request=request,
)
)
conversion_adjustment_result = response.results[0]
print(
f"Uploaded conversion that occurred at "
f'"{conversion_adjustment_result.adjustment_date_time}" '
f"from Gclid "
f'"{conversion_adjustment_result.gclid_date_time_pair.gclid}"'
f' to "{conversion_adjustment_result.conversion_action}"'
)
# Iterate every row (subscriber) and call the "adjust conversion" function for it
df.apply(lambda row: adjust_offline_conversion(client=client
, customer_id=customer_id
, conversion_action_id='xxxxxxx'
, gclid=row['click_id']
, conversion_date_time=row['subscription_time']
, adjustment_date_time=datetime.utcnow()
, restatement_value=row['revenue'])
, axis=1)
I managed to solve it in the following way:
The conversion upload and adjustment are not supported in the Batch Processing, as they are not listed here.
However, it is possible to upload multiple conversions in one request since the conversions[] field (list) could be populated with several conversions, not only a single conversion as I mistakenly thought.
So if you're uploading conversions/ adjusting conversions you can simply upload them in batch this way:
Instead of uploading one conversion:
request.conversions = [conversion]
Upload several:
request.conversions = [conversion_1, conversion_2, conversion_3...]
Going the same way for conversions adjustment upload:
request.conversion_adjustments = [conversion_adjustment_1, conversion_adjustment_2, conversion_adjustment_3...]
Actually I'm trying to to shift the time, the application I'm working on is in UTC and I'm working in IST.
I've used both BEAN Shell pre processor and shiftTime function
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
int AddSeconds= 00; //this variable needs to be customized as per your need
int AddMinutes= 392; //this variable needs to be customized as per your need
int AddHours= 00; //this variable needs to be customized as per your need
Date now = new Date();
Calendar c = Calendar.getInstance();
c.setTime(now);
c.add(Calendar.SECOND, AddSeconds);
c.add(Calendar.MINUTE, AddMinutes);
c.add(Calendar.HOUR, AddHours);
Date NewTime = c.getTime();
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
String mytime = df.format(NewTime);
vars.put("NewTime",mytime);
Shift Time :
"${__timeShift(yyyy-MM-dd'T'HH:mm:ss.SSS'Z',,PT393M,,)}"
Bun when I run the HTTP Request in Jmeter the time format is coming in 12Hrs only instead of 24 Hr
Also Time shift is taking in weird manner, I've tried all options from Stackoverflow from last 2 days and unable to achieve my task to convert IST to UTC.
This is what I'm using in Jmeter Post body
enter image description here
And this is what I'm getting as result
enter image description here
Time formats are getting totally mismatched here, can someone please help me to convert IST to UTC correctly while playing with these time formats and functions.
I don't think you can use __timeShift() function for getting the date in the different timezone, it will return you the current (default) one
So if you need to add 392 minutes to the current time in the time zone different from yours - you will have to go for __groovy() function and use TimeCategory class
Example code:
${__groovy(def now = new Date(); use(groovy.time.TimeCategory) { def nowPlusOneYear = now + 392.minute; return nowPlusOneYear.format("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"\,TimeZone.getTimeZone('IST')) },)}
Demo:
If you need to get the time in UTC just change IST to UTC
${__groovy(def now = new Date(); use(groovy.time.TimeCategory) { def nowPlusOneYear = now + 392.minute; return nowPlusOneYear.format("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"\,TimeZone.getTimeZone('UTC')) },)}
More information: Creating and Testing Dates in JMeter - Learn How
Also be informed that since JMeter 3.1 you're supposed to be using JSR223 Test Elements and Groovy language for scripting
Just adding one more way to do this via bean shell preprocessor and it worked for me pretty well.
Here is the code to use... here -325 minutes is the difference between IST and UTC
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
int AddSeconds= 00; //this variable needs to be customized as per your need
int AddMinutes= -325; //this variable needs to be customized as per your need
int AddHours= 00; //this variable needs to be customized as per your need
Date now = new Date();
Calendar c = Calendar.getInstance();
c.setTime(now);
c.add(Calendar.SECOND, AddSeconds);
c.add(Calendar.MINUTE, AddMinutes);
c.add(Calendar.HOUR, AddHours);
Date NewTime = c.getTime();
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
String mytime = df.format(NewTime);
vars.put("NewTime",mytime);
// NewTime is your jmeter variable
Playing in groovyConsole with DateTimeFormatter and DateTimeFormatterBuilder
String inputDateString = "31.2.58" // german date format
dtfIn = DateTimeFormatter
.ofPattern ( "d.M.uu" )
.withResolverStyle ( ResolverStyle.STRICT )
dtfIn.parse(inputDateString) // ERROR as expected
...but
// with base range 1937-2034
dtfIn = new DateTimeFormatterBuilder()
.appendPattern("d.M.")
.appendValueReduced(ChronoField.YEAR, 2, 2, Year.now().getValue() - 80)
.parseStrict()
.toFormatter()
dtfIn.parse(inputDateString) // Result: 1958-02-28
So DateTimeFormatterBuilder with .parseStrict() would parse rather SMART, which DateTimeFormatterBuilder shouldn't do at all but either STRICT or LENIENT (?)'
With day numbers over 31 I'll get an error.
The problem seem to be .appendValueReduced(). Without it I'd become an error as expected.
What do I do wrong?
Thanks
Rawi
DateTimeFormatter from DateTimeFormatterBuilder.toFormatter() is indeed SMART as documented:
The resolver style will be SMART
To obtain STRICT one has to use DateFormatter.withResolverStyle(ResolverStyle)
in this case as follows:
.toFormatter().withResolverStyle(ResolverStyle.STRICT);
I'm using lastLogonTimeStamp to track the users last logon time as the following code:
$Domain = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
$ADSearch = New-Object System.DirectoryServices.DirectorySearcher
$ADSearch.SearchRoot ="LDAP://$Domain"
$ADSearch.SearchScope = "subtree"
$ADSearch.PageSize = 100
$ADSearch.Filter = "(objectClass=user)"
$properies = #("distinguishedName",
"sAMAccountName",
"mail",
"lastLogonTimeStamp")
foreach ($pro in $properies) {
$ADSearch.PropertiesToLoad.add($pro)
}
$userObjects = $ADSearch.FindAll()
foreach ($user in $userObjects) {
$logon = $user.Properties.Item("lastLogonTimeStamp")[0]
$lastLogon = [datetime]::fromfiletime($logon)
$lastLogon= $lastLogon.ToString("yyyy/MM/dd")
$lastLogon
}
I've gotten so far:
1601/01/01
1601/01/01
3/12/2012
1601/01/01
3/19/2015
This is not the first time I'm bloody confused about the 1601/01/01 value. And I've read also the MS document about this value and for me it's nonsense, it does not describe much what is the purposes of it. Not only lastLogonTimeStamp has this output, many other attributes have return this as well. So my questions are:
What is the purpose of this value?
In this case, what should I return as a proper human readable output ? (This attribute is not valid for this user?)
There is a known bug with the "last logon timestamp" and Windows 2016 domain controllers.
LDAP simple bind are not updating the last logon timestamp like previous OS ( 2012, 2008 ). Be careful.
I spent 2 months with MS on this. A patch will be released eventually... but for now it's not fixed.
I have got below code, where I am sending the formatted date and time to my XSLT and which is giving a XML as output.
#importXSLT "tcm:228-190529-2048" As expandXSLT
#importXSLT "tcm:228-642694-2048" As renderXSLT
Dim xml, currentDateTime, datLong , datLongTime , fullDate
Set xml = getNewDomDocument()
xml.loadXML TDSE.GetListPublications(3)
expandXSLT.input = xml
Call expandXSLT.addParameter("publication", Component.Publication.Id)
expandXSLT.transform
xml.loadXML(expandXSLT.output)
'WriteOut xml.xml
currentDateTime = now()
datLong = FormatDateTime(currentDateTime, 1)
datLongTime = FormatDateTime(currentDateTime, 3)
fullDate = datLong &" "& datLongTime
renderXSLT.input = xml
Call renderXSLT.addParameter("currentPublishedDate", CStr(fullDate))
renderXSLT.transform
WriteOut renderXSLT.output
Set xml = Nothing
Now above logic for doing date formatting is same for two outputted XML, but suprising I am getting different output for both the files.
First File gives - Sunday, October 23, 2011 8:52:36 AM as output
Second File gives - 23 October 2011 09:14:45 as output.
Please suggest what can be reason as well as solution also, and one more thing if I want output as below for both the file as 23 October 2011 09:14:45 AM
Thanks!!
Before you do the date formatting, try to explicitly set the locale using something like SetLocale(2057).
2057 is UK format which seems to be what you want, otherwise look at this Locale ID Chart to find the correct value.