0

I am running a query between several tables and I am running into an issue between comparing two time columns on separate tables: "rc1_time" is in a string format and "osemplog_time" is in a time format. both are time only with no date

rc1_time's contents look like this '10560684' which corresponds to HH24MISSMS

osemplog_time's contents look like 07:57:02.917455


  1. how do I format the rc1_time into a "time format" with no date?
  2. what are some options for comparing the two times?

I am newbie at this exposition on your answers would be welcome

below is my query

SELECT
"public".payroll_master.prm1_name,
"public".payroll_master.prm1_oe_init,
"public".receipt.rc1_init,
"public".employee_log.osemplog_ipaddress,
"public".employee_log.osemplog_event,
"public".receipt.rc1_date,
"public".employee_log.osemplog_logdate,
"public".receipt.rc1_code,
"public".employee_log.osemplog_logname,
"public".oslogname.lognm_empname,
"public".receipt.rc1_arname,
"public".receipt.rc1_arnum,
"public".receipt.rc1_time,
"public".employee_log.osemplog_logtime
FROM
"public".receipt
INNER JOIN "public".employee_log ON "public".receipt.rc1_date = "public".employee_log.osemplog_logdate
INNER JOIN "public".payroll_master ON "public".payroll_master.prm1_oe_init = "public".receipt.rc1_init
INNER JOIN "public".oslogname ON "public".oslogname.lognm_empname = "public".payroll_master.prm1_name AND "public".oslogname.lognm_name = "public".employee_log.osemplog_logname
WHERE
"public".receipt.rc1_code = 'CA'
AND
"public".employee_log.osemplog_logdate = "public".receipt.rc1_date

ORDER BY
"public".receipt.rc1_init ASC
3
  • 1
    which corresponds to HHMMSSSS - what exactly do 4 digits for seconds mean? A minute can't have more than 59 seconds, so why does the format have 4 digits? And is HH in 24 hour format (00-23) or 12 hour format? Commented Feb 22, 2016 at 23:05
  • @a_horse_with_no_name The docs say that SSSS is "seconds past midnight," although this is almost certainly not what the OP meant since that would not require having hours or minutes. Definitely a detail the OP needs to figure out. Commented Feb 22, 2016 at 23:24
  • HH24MISSMS i guess would be the order for the rc1_time, but it is a string. I'll edit that. thanks!! Commented Feb 22, 2016 at 23:37

1 Answer 1

1

Question as stated

You can represent a time without a date using the time data type. To convert a string from a given format into one, you can go through the to_timestamp function and then cast to time:

SELECT to_timestamp('10560684', 'HH24MISSUS')::time;
SELECT to_timestamp('07:57:02.917455', 'HH24:MI:SS.US')::time;

The basic idea is that you parse the time string using to_timestamp. The resulting timestamp will have a default date, and casting to time will remove the date, leaving only the parsed out time portion.

Assumptions:

  • Your hours are in 24-hour clock format (13-23 for 1 PM to 11 PM and 00 for midnight). If they are not 24 hour times, then you are missing the AM/PM designation and will need to sort that out.
  • The second "SS" you mention in your first pattern is actually a fractional part of seconds. If not, you'll need to adjust the pattern. If you don't care about the fractional seconds, you might consider just leaving the US and the .US off entirely and working only at the seconds level. Note that US interprets 84 to be 0.84 seconds, not actually 84 microseconds (0.000084 seconds).

Ultimately, you will need to either provide much more precise details about the format or figure out the correct format string yourself. Rather than worry about those details, I've tried to exemplify the general mechanism and leave those to you.

Comparison is then trivial. You just use PostgreSQL's operators (<, >, =, etc.):

SELECT to_timestamp('07:57:02.917455', 'HH24:MI:SS.US')::time < to_timestamp('10560684', 'HH24MISSUS')::time;

Other considerations

  • Be aware of time zone issues if you are working across them. You'll want to look at timetz (short form of time with time zone) or timestamptz (short form of timestamp with time zone) if you need to deal with time zones. Generally, I would recommend including time zone handling up front in case it becomes a problem later.

  • In this case, why not build a complete timestamp? You already have the dates: "public".receipt.rc1_date and "public".employee_log.osemplog_logdate.

    You don't specify the data types, but whatever the forms of those are, it should be possible. For example, if they are actual date objects, then:

    SELECT to_timestamp(to_char("public".receipt.rc1_date, 'YYYY-MM-DD')||' '||"public".receipt.rc1_time, 'YYYY-MM-DD HH24MISSMS');
    

    If they are strings of the form 'YYYY-MM-DD', then:

    SELECT to_timestamp("public".receipt.rc1_date||' '||"public".receipt.rc1_time, 'YYYY-MM-DD HH24MISSMS');
    

    And so on. Now you have a real timestamp, which makes simple great/less than comparison much, much easier.

  • In my experience, it's extremely rare that you actually want to test time stamps with fractional second precision for equality. You might want a more tolerant equality check, something like SELECT t1 - t2 < interval '5 seconds', but this is really up to the application.

Sign up to request clarification or add additional context in comments.

5 Comments

no time zone issues thankfully, and oddly enough both the dates are 'YYYY-MM-DD' so real timestamp would work better thanks! have mercy on me oh lords of programming. the database I'm working with is a mishmash of converted cobol, sorta converted cobol, and some new modern tables. its an adventure everyday.
@JasonDossett I would still recommend storing the times with a timezone and handling it all up front. PG has excellent capabilities to help out with them. Then you never have to worry about it when they eventually do come up; not handling them is some pretty big technical debt. Also, if this solves your problem, please consider accepting the answer (or someone else's answer if they post something that works better for you).
i can't change the formats coming out of the tables to my query unfortunately, its a database from an electronic health record. the vendor has enough trouble keep the damn thing operational without me messing with the backend too. i get what i get.
@JasonDossett Fair enough. It's no surprise they have trouble keeping it working if this is how they store timestamps, though; it doesn't exactly scream "competent."
competent. lol.the entire program is pushing around.....a billion lines of code and 3300 tables. I used to code for the vendor a few years ago. damn thing is a frankenstein monstrosity of cobol, postgresql, java, and a couple other languages

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.