JulianToDate problem

I want to convert a Modified Julian Date (MJD)  & Time to seconds in normal IGOR siderial time.  

I can convert MJD to Julian date but the JulianToDate function does not convert it to the format given in description.  For example rather than the expected format for format 1 of dd/mm/year  I get 6/7/2021 instead of 06/07/2021.  

An additional difficulty is that there does not appear a way of extracting the time.

The great thing about the Igor forum is that invairably someone, somewhere has already done what your asking, and likely fogotten:

Function/S MJD2DateTime(double MJD[,int T,int D])
    // defaults
    T = ParamIsDefault(T) ? 2 : T // 24hr time, no seconds
    D = ParamIsDefault(D) ? 2 : D // e.g. dayStr monthStr DD, YYYY

    double JD = MJD + 2400000.5 // convert to Julian

    return Secs2Time((JD - 0.5) * 86400,T) + ", " + JulianToDate(JD + 0.5,D)

Check out this project which contains all kinds of functions to manipulate Julian, sidereal, ephemeris, and true solar time. Hopefully there is something useful in there for you.

Your are absolutely right cpr - the forum is jam-packed with experts who can answer questions on the most arcane or obscure nature, and I am glad you were able to respond.

I will need some explanation of your function.  What is the format of the wave MJD?  My data has the format for examp[le, 59396.023297 which is 2021-07-01 00:33:32 plus some frctional bits of seconds to a millisecond or so.

I am also unfamiliar with the function ParamIsDefault(pName) - how does it operate in the function?

I have not been able to get your project up and working because, as a private user, I have not yet purchased Version 9 yet.  However, From what I can see there are some interesting functions there that are not dependant on version.  It is quite dificult to find particular topics in the projects files and I had not come accross yours.

Just some clarifications of the code used in cpr's function example:

- The function inputs are all variables (Type Variable), but since Igor 7 you can actually declare the type more precisely like in C: double = double-precision (64 bit) floating-point and int = 64-bit integer.

MDJ is not a wave but a single variable. If you want to convert the contents of a whole wave you would need to pass each entry through this function like so:

JD_TextWave = MJD2DateTime(MDJ_Wave[p])

- the function uses optional input parameters T and D, which are indicated by the square brackets. Yo can read more about this feature here:

DisplayHelpTopic "Optional Parameters"

This chapter also explains the function ParamIsDefault(), which is used to check whether an optional parameter ist set or not. In above function the parameters T and D control the output format of Secs2Time() and JulianToDate(). For example, if you call the function with T=3 you will get seconds in the output as well. If you don't set any of the optional parameters then T and D will both be 2.

Hi Mike

MJD is as you would expect, days since 17 November 1858, as a variable. So if you execute the function the basic time and date are returned as a string - you could easily modify the function to get Igor DateTime:

Print MJD2DateTime(59396.023297)
  00:33:33, 1/7/2021

There are optional parameters T and D which are the format arguments of JulianToDate and SecsToTtime - if you don't provide these the format is set to 24 hour time (option 2) and ISO day-date format (option 2), ParamIsDefault is checking if the optional parameters were passed. You could pass the optional parameters to get a different representation, e.g.:  

Print MJD2DateTime(59396.023297,T=0,D=0)
  00:33, 7/1/2021

I guess when I wrote it I wanted all the options available,but the default to be option 2 for both. Though I see there is no way to see fractional seconds so if you needed that you could use this modification:

Function/S MJD2DateTime(double MJD[,int T,int D,int S])
    // defaults
    T = ParamIsDefault(T) ? 2 : T // 24hr time, no seconds
    D = ParamIsDefault(D) ? 2 : D // e.g. dayStr monthStr DD, YYYY

    double JD = MJD + 2400000.5 // convert to Julian

    return Secs2Time((JD - 0.5) * 86400,T,S) + ", " + JulianToDate(JD + 0.5,D)

Which when testing gives:

Print MJD2DateTime(59396.023297,T=3,D=0,S=5)
  00:33:32.86081, 7/1/2021

That Astronomical Algorithms project was written when testing the IP9 Beta so uses whatever new features there where - it could be ported back to IP8 easily but no further I think. Any function that has multiple return can be modified thusly, if you wish:

// Allowed in IP9
Function someFunc()
    [double param1, double param2] = multipleReturnFunc()

// Allowed in IP8
Function someFunc()
    double param1,param2
    [param1,param2] = multipleReturnFunc()


If you use IP6 change any int,double etc to Variable - I tend to use double and int as its easier for me to type.

In reply to by cpr

Hi cpr,

the modification does the job of returning the Time including seconds with decimals which is what I need.  The issue with the way in which Julian2Date() works is still at odds with how the manual indicates:  accordning to help, format 1 should give  dd/mm/year but prints d/m/year.  This appears to happen in my ip8 and your ip9.  I want to get the string output to yyyymmdd format - this is not a big problem because, I note that options 3 provides spaces for omitted zeros in the format. 

BTW my application is conversion of the dates and times of meteor events given in MJD to UT date and time.

This has been an interesting exercise for me and I have learnt IP features that are new to me.  Great help and product.

Ah, I see. Well where there's a will, there's a kluge: 

Function/S MJD2DateTime(double MJD[,int T,int S])
    // defaults
    T = ParamIsDefault(T) ? 2 : T       // 24hr time, no seconds

    double JD = MJD + 2400000.5 // convert to Julian
    String JulianDateStr = JulianToDate(JD + 0.5,0)
    int day,month,year
    sscanf JulianDateStr,"%d/%d/%d",day,month,year
    sprintf JulianDateStr,"%04d%02d%02d",year,month,day

    return Secs2Time((JD - 0.5)*86400,T,S)+", "+JulianDateStr


Print MJD2DateTime(59396.023297,T=3,S=5)
  00:33:32.86081, 20210107