With the help of the excellent answers from @sideview and @jmccr78 I came up with what I believe to be an improved solution (simplified and robust).
eval _time_UTC = _time
- (strptime("2000-01-01 +00:00", "%F %:z") - strptime("2000-01-01 " . strftime(_time, "%:z"), "%F %Z"))
| eval time_in_UTC = strftime(_time_UTC, "%F %T UTC")
This works by computing the UTC offset of the timezone configured in the user preferences and subtracting it from the time (similar to the other answers). However the timezone offset is calculated simply by using a reference date (I chose 2000-01-01 arbitrarily) and parsing it twice, first using the UTC timezone and then the users configured timezone, and the difference of the two yields the timezone offset.
This method can easily be extended to support converting to an arbitrary timezone.
eval _timezone = "AEST"
| eval _time_AEST = _time
- (strptime("2000-01-01 +00:00", "%F %:z") - strptime("2000-01-01 " . strftime(_time, "%:z"), "%F %Z"))
+ (strptime("2000-01-01 +00:00", "%F %:z") - strptime("2000-01-01 " . _timezone, "%F %Z"))
| eval time_in_AEST = strftime(_time_AEST, "%F %T " . _timezone)
This works by first subtracting the UTC offset of the timezone as configured in the users preferences, then adds on the UTC offset of the timezone you configure (in this example AEST , but could be -05:30 or any valid Splunk timezone identifier).
A couple of things to remember:
in the example, Splunk interprets the _time_AEST variable as seconds since epoch (1970-01-01 00:00:00 UTC), and so technically Splunk is interpreting this as a different 'real world' time -- if you attempt to print the timezone of the date, it will incorrectly report the users configured timezone. Instead, whenever printing this date always include the timezone manually and don't use the %Z timezone formats (as is done in the last line of the example).
I discovered that Splunk Light Version 6.4.1.2 seems to have a bug where it ignores the users timezone and always reports UTC. Using the above method will not break under such circumstances.
The above can easily be converted to a macro. However I have found that when passing arguments to a macro it is best to use pre-calculated fields, rather than expressions (since expressions will have their " quotes stripped when passed as arguments to a macro).
Splunk does not seem to support the tz database - it only seems to support timezones with a fixed offset from UTC. For example, if you live in Sydney you would usually select the "Australia/Sydney" timezone from timezone dropdowns - however this item is not available in Splunks list of timezones in the user preferences. I believe this is because Sydney adheres to Day Light Savings time. If you wish to run a query using local time of an area which is not always a fixed offset from UTC, then you will have to upload a timestamp to Splunk in local time (of course this only applies if you are in control of your input sources) and not have Splunk interpret it (i.e. use a different field other than the _time property). For our use case, we are uploading the 'real world time' using time since Epoch (assigned to the _time property), and additionally upload a timestamp formatted as a date in local time field which Splunk interpets as a string. This gives Splunk enough information to assign the correct time to the event, but also allows us to run queries against the local time where the data is sourced from.
... View more