another technical blog...technically

Saturday, February 24, 2018

Blue Prism / DateTime / Code Stage / Locale issue

Since I’m at home with something like a broken shoulder (the right one), I got a lot of draft blog posts and a wonderful windows plugin named Dictate I think it’s the time to recover just a bit of work.
Today I want to talk about the behavior or daytime values when passed as an argument to code- stages. Even if Blue Prism discourages the use of code stages, I believe that this feature is one of the most interesting of them all and also helps to unleash the power of RPA. The problem with DateTime values in code stages is that BP represents them internally in UTC which could not be your locale (eg I work in Italy UTC+1)

Collection populated manually
Just passed as argument and returned

So BP suggests the following

If you do need to use a code stage then the following amendment at the end of the line will yield the behavior you expect:  The point is that you cannot always pre-process data, for example, if we take data from DB we cannot pre-process them but we have to deal with wrong data like you can see in the images below

Data from DB

Wrongdata after collection

The solution is just to post-process the data with this piece of code.
Dim dtItemValue As DateTime
Dim newDtItemValue As DateTime
Dim localZone As TimeZone
Dim span As TimeSpan

For Each row As DataRow In data.Rows
 For Each column As DataColumn In data.Columns
    dtItemValue = Nothing
    newDtItemValue = Nothing
    
    If column.DataType = System.Type.GetType("System.DateTime") Then
     dtItemValue = row(column)
     localZone = TimeZone.CurrentTimeZone
     span = localZone.GetUtcOffset(dtItemValue)
     spanString = span.ToString
     dtItemValue = dtItemValue.Add(span)
     newDtItemValue = dtItemVAlue.ToLocalTime
     row.SetField(Of DateTime)(column, newDtItemVAlue)
    End If
 Next
Next

dataOut = data
You have to take care that BP passes arguments by value and not by reference so could be necessary to use this code every time you passed the collection into the code-stages. A special credit to Raffaele Ecravino and Antonio Durante for this brief piece of code.
written in: Milano MI, Italia

10 comments:

  1. Ciao,

    Wonderful post. Truly useful!

    Now, I'm facing A "similar" issue.

    I need to insert today's date in a word document, in the following format "02 May 2018".

    I'm using this 'FormatDate(Today(), "dd MMMM yyyy")' (in an MS Word VBO - Type Text Action).

    But, I got printed "02 mei 2018". I know that's why our serverare in Belgium, but... even after changing the ´M Windows Region and Language to English (UK), I'm still getting it in Dutch when, I run it (in the diagram).

    Any idea?

    ReplyDelete
    Replies
    1. Hi,

      i think you can solve the problem with a code block:

      https://docs.microsoft.com/it-it/dotnet/standard/base-types/custom-date-and-time-format-strings


      DateTime.Now().ToString("dd MMMM yyyy",CultureInfo.CreateSpecificCulture("en-US"))

      I have not tested it but it should be ok ;)

      Delete
    2. Thank you so much! But it won't compile! :( (I'm in BP v4)

      Delete
    3. I've tried right now, just use .Now as a property and not as a method and it will works.

      string s = DateTime.Now.ToString("dd MMMM yyyy", CultureInfo.CreateSpecificCulture("en-US"));

      Delete
    4. Otherwise, post the compile error ;)

      Delete
  2. Thank you! I don't get ANY compile error, but... when trying to run it, it won't run and, the issue is:

    "Internal : Could not run the object because one of the code stages has a compile error, use Check for Errors for a list of problems"

    ReplyDelete
  3. Solved by creating this SQL (Stored Procedure):

    "
    CREATE PROCEDURE PID0156_GET_CURRENT_DATE
    -- Add the parameters for the stored procedure here
    @CURRENT_DATE date = varchar
    AS
    BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    -- Insert statements for procedure here

    SELECT CONVERT(VARCHAR(11), convert (date, @CURRENT_DATE, 112), 106) AS [CURRENT_DATE]


    END
    GO
    "

    Thank you so much by your help!

    ReplyDelete
    Replies
    1. Hi macs, i think this is an overkill, if you want to telle me more about the error, we can drill down and solve it

      Delete
  4. Forgot to add:

    I pass @CURRENT_DATE as FormatDate(Today(), "yyyyMMdd").

    You may ask why I do this?

    I do it for two reasons:

    1. To be able to convert any date.
    2. It won't be the first time that date on the program (BP, in this case) differs from date on the DB (generally, just hours).

    ReplyDelete
  5. Thank you so much! I know it's not the best option... but... since it's working :)

    On the other hand, I do not know what else can I tell you about the error. I told you already already all that I know...


    Thank you so much anyway... You are a *!!!

    ReplyDelete

Because of a lot of SPAM about courses, I need to moderate all comments here.
I ensure you that I will answer whenever possible (if you are not a spammer).

Me, myself and I

My Photo
I'm just another IT guy sharing his knowledge with all of you out there.
Wanna know more?