#1
  1. A Change of Season
    Devshed Loyal (3000 - 3499 posts)

    Join Date
    Mar 2004
    Location
    Next Door
    Posts
    3,477
    Rep Power
    221

    php's date('c') ISO 8601 date


    [[ split from php's date('c') ISO 8601 date --requinix ]]

    Clean? Not exactly but working well.

    PHP Code:
    class Custom_functions {

            
    function 
    set_timezone_by_user_id($user_id)
      {
        
    $CI = & get_instance();
        
    $sql "SELECT * FROM launch_owners WHERE id = ?";
        
    $query_timezone $CI->db->query($sql, array($user_id));
        
    date_default_timezone_set(''.$query_timezone->result_array()[0]['timezone'].'');
      }

    .
    .
    .

    CRUD

    PHP Code:
    $data = array(
                     
                    
    'broadcast_access_date' => date('c',strtotime($_POST['broadcast_access_date'])), 
                    
    'release_after_days_evergreen ' => $_POST['release_after_days_evergreen']);
                    
    $this->db->where('id'$id);
                    
    $this->db->update('launch_plcs'$data); 
    PHP Code:
    public function evergreen_sales_page_timer($hashed_owner_email$launch_id$email=null)
            {
    //Before all math            
    $this->set_timezone($hashed_owner_email);
    ..
    .


    Last edited by requinix; May 7th, 2018 at 02:32 AM.
  2. #2
  3. Impoverished Moderator
    Devshed Supreme Being (6500+ posts)

    Join Date
    Mar 2007
    Location
    Washington, USA
    Posts
    16,750
    Rep Power
    9646
    If the user's timezone changes then all the dates will be wrong.

    Store everything in UTC. You can reformat the date in PHP according to the user's timezone, but the dates in the database must be all UTC.
  4. #3
  5. A Change of Season
    Devshed Loyal (3000 - 3499 posts)

    Join Date
    Mar 2004
    Location
    Next Door
    Posts
    3,477
    Rep Power
    221
    Originally Posted by requinix
    If the user's timezone changes then all the dates will be wrong.
    Just to make sure we're on the same page, the user might be in UK, but the account TZ could be UTC or Eastern or ....

    About this:

    Originally Posted by requinix
    Store everything in UTC. You can reformat the date in PHP according to the user's timezone, but the dates in the database must be all UTC.
    Ok, let's see if I got this right:

    1 - I store everything as UTC.
    2 - When retrieving, convert it from UTC to user's TZ (For example Australia/Melbourne). To do so, I use this code:
    PHP Code:

    //For example, how many days has the prospect been in the sequence:
     
    $TZ $CI->custom_functions->set_timezone_by_launch_id($launch_id); // Get the TZ of the account that launch belongs to

    $date->setTimezone(new DateTimeZone($TZ)); 
    $sql "
        SELECT date_added
    FROM   launch_launch_prospect
    WHERE  prospect_id = ?
           AND launch_id = ? "
    ;

    $query $CI->db->query($sql, array($prospect_id$launch_id));
    $date1 = new DateTime(date('Y-m-d'));
    $date2 = new DateTime($query->result_array()[0]['date_added']);
    return 
    $days $date2->diff($date1)->format("%a"); 
    Right?
    Last edited by English Breakfast Tea; May 6th, 2018 at 09:31 AM.
  6. #4
  7. Impoverished Moderator
    Devshed Supreme Being (6500+ posts)

    Join Date
    Mar 2007
    Location
    Washington, USA
    Posts
    16,750
    Rep Power
    9646
    My point was not where the user was but where the user might move to. If you stored in their timezone, say UK, and for whatever reason they wanted to change to US East or Turkey or something, then all those dates you have in the database would be wrong. And fixing them would be a huge hassle.

    So yes, store with UTC and convert for the user when needed. Your code looks like a mashup from two or three places though.
    PHP Code:
    function date2database(DateTime $dt) {
        
    $dt = clone $dt;
        
    $dt->setTimezone(new DateTimeZone("UTC"));
        return 
    $dt->format("Y-m-d");
    }

    function 
    datetime2database(DateTime $dt) {
        
    $dt = clone $dt;
        
    $dt->setTimezone(new DateTimeZone("UTC"));
        return 
    $dt->format("Y-m-d H:i:s");
    }

    function 
    database2datetime($datetimeDateTimeZone $tz) {
        
    $dt = new DateTime($datetime, new DateTimeZone("UTC"));
        
    $dt->setTimezone($tz);
        return 
    $dt;

  8. #5
  9. A Change of Season
    Devshed Loyal (3000 - 3499 posts)

    Join Date
    Mar 2004
    Location
    Next Door
    Posts
    3,477
    Rep Power
    221
    Originally Posted by requinix
    My point was not where the user was but where the user might move to. If you stored in their timezone, say UK, and for whatever reason they wanted to change to US East or Turkey or something, then all those dates you have in the database would be wrong. And fixing them would be a huge hassle.

    So yes, store with UTC and convert for the user when needed. Your code looks like a mashup from two or three places though.
    PHP Code:
    function date2database(DateTime $dt) {
        
    $dt = clone $dt;
        
    $dt->setTimezone(new DateTimeZone("UTC"));
        return 
    $dt->format("Y-m-d");
    }

    function 
    datetime2database(DateTime $dt) {
        
    $dt = clone $dt;
        
    $dt->setTimezone(new DateTimeZone("UTC"));
        return 
    $dt->format("Y-m-d H:i:s");
    }

    function 
    database2datetime($datetimeDateTimeZone $tz) {
        
    $dt = new DateTime($datetime, new DateTimeZone("UTC"));
        
    $dt->setTimezone($tz);
        return 
    $dt;

    Hi;

    I am pretty sure we're doing the same thing.

    Mush up as in what?

    (Also how come you got datetime2database? Wouldn't use it.)

    Damn you write clean code.
  10. #6
  11. A Change of Season
    Devshed Loyal (3000 - 3499 posts)

    Join Date
    Mar 2004
    Location
    Next Door
    Posts
    3,477
    Rep Power
    221
    arrrghhhhh I'm so mad right now I applied what I got from your suggestion and it doesn't work.

    This obviously doesn't make sense to
    1 - Store and UTC
    2 - When retrieve convert to timezone. Then what's stored be different from what's retrieved.

    To INSERT
    PHP Code:
    $_POST['offer_open_date'] = $this->custom_functions->date_to_UTC(new DateTime($_POST['offer_open_date']));
    $_POST['offer_close_date'] = $this->custom_functions->date_to_UTC(new DateTime($_POST['offer_close_date']));    

    $data = array(
    'offer_open_date' => $_POST['offer_open_date'],
    'offer_close_date' => $_POST['offer_close_date']
    );
    $this->db->insert('launch_launches'$data); 
    To RETRIEVE

    This doesn't show the right results. For example, if I store May 7th (UTC), it retrieves at May 6 (America/Lima).

    Code:
    <div class="form-group">
    <label for="">Offer Open Date</label>
    <input type="text" class="form-control selector" name = "offer_open_date" 
    value = "<?php echo $this->custom_functions->offer_open_date_by_launch_id($launch['id'], $launch['offer_open_date']);?>" 
    id = "datepicker">
    </div>
    PHP Code:
    function offer_open_date_by_launch_id($launch_id$offer_open_date)
      {
        
    $CI = & get_instance();
        
    $tz $CI->custom_functions->get_timezone_by_launch_id($launch_id);
        
    $offer_open_date $CI->custom_functions->database_to_date($offer_open_date, new DateTimeZone($tz));
        return 
    $offer_open_date $offer_open_date->format('Y-m-d');
      }
    function 
    date_to_UTC(DateTime $dt
      {
        
    $dt = clone $dt;
        
    $dt->setTimezone(new DateTimeZone("UTC"));
        return 
    $dt->format("Y-m-d");
      }

    function 
    database_to_date($datetimeDateTimeZone $tz) {
        
    $dt = new DateTime($datetime, new DateTimeZone("UTC"));
        
    $dt->setTimezone($tz);
        return 
    $dt;
    }  



    function 
    get_timezone_by_launch_id($launch_id)
      {
        
    $CI = & get_instance();
        
    $sql "
        SELECT timezone FROM launch_owners
        INNER JOIN launch_launches ON launch_launches.user_id = launch_owners.id
        AND launch_launches.id = ?"
    ;
        
    $query_timezone $CI->db->query($sql, array($launch_id));
        return 
    $query_timezone->result_array()[0]['timezone'];
      }

    function 
    set_timezone_by_launch_id($launch_id)
      {
        
    $CI = & get_instance();
        
    $sql "
        SELECT timezone FROM launch_owners
        INNER JOIN launch_launches ON launch_launches.user_id = launch_owners.id
        AND launch_launches.id = ?"
    ;
        
    $query_timezone $CI->db->query($sql, array($launch_id));
        
    date_default_timezone_set(''.$query_timezone->result_array()[0]['timezone'].'');
      } 
    Last edited by English Breakfast Tea; May 6th, 2018 at 11:59 PM.
  12. #7
  13. Impoverished Moderator
    Devshed Supreme Being (6500+ posts)

    Join Date
    Mar 2007
    Location
    Washington, USA
    Posts
    16,750
    Rep Power
    9646
    As should be apparent in the code, datetime2database would be for dates+times. And really date2database isn't good because of the problem you see.

    So hold on. Are you not working with times? Just dates? Dates that are entered by the user, or calculated using data entered by the user?

    Because if that's the case then 99% of this timezone stuff is moot.
  14. #8
  15. A Change of Season
    Devshed Loyal (3000 - 3499 posts)

    Join Date
    Mar 2004
    Location
    Next Door
    Posts
    3,477
    Rep Power
    221
    Originally Posted by requinix
    As should be apparent in the code, datetime2database would be for dates+times. And really date2database isn't good because of the problem you see.

    So hold on. Are you not working with times? Just dates? Dates that are entered by the user, or calculated using data entered by the user?

    Because if that's the case then 99% of this timezone stuff is moot.
    Hey;

    No times only dates.

    Here are the requirements I have. To be honest, we got it before this change, but there we go:

    This system is very simple. It allows anyone with an email list to sign up and create 'real count down timers" for their pages and add them to their sales pages and pre-launch pages using Javascript. We have done all the code (most of it with u and Kicken) and all is working sweet.

    The very last part was to check the page access permission. For example if the user goes to a page 'after the expiry date', they get redirected to 'offer closed' page.

    Hpw do we know when they joined? By the api call we receive from auto-responders.

    Now there are 2 types of launches:

    1 - Broadcast (with specific end date, like Christmas Eve)
    2 - Evergreen. Evergreen means each subscriber gets their own deadline. One example of this happens to be one of the most popular campaigns with Deadline Funnel - a “new subscriber discount.”

    Account holders can set their account on a specific timezone and run their launches there. For example 'I want the offer page to open 4 days after prospect has joined, stay open for 3 days, and close after 3 days.

    The video on this page shows exactly what it does.

    Again the code we had until today's changes, looked all good. When you brought up the UTC, I thought you might be right as always, but when implemented, it didn't really make sense.

    I am gonna revert back to that code.

    Is it all clear or do you want me to show you more code or specs?

    I am ready to close this section and continue testing.

    Thanks
  16. #9
  17. Impoverished Moderator
    Devshed Supreme Being (6500+ posts)

    Join Date
    Mar 2007
    Location
    Washington, USA
    Posts
    16,750
    Rep Power
    9646
    But... you need times for some of this.

    Like if it's midnight on Christmas Day in Australia, does that mean that access has expired for people in the US?
    If I join at my 11:59pm on Monday, and the offer is good for 2 days, then does it expire (a) Wednesday at my midnight, (b) Wednesday at your midnight, or (c) Wednesday at my 11:59pm?

    [edit]
    If you only care about dates, like really you do only care about dates, then you can store the dates without timezone information in the database. Dates themselves don't really have timezones - they're almost always according to an observer in some timezone, but the date itself is just a date. Christmas is December 25, not December 25 according to one particular timezone. When you check the date relative to an observer A is when you take into account timezone: if the date is local to A then you check their local time, but if it's relative to another observer B then you take the current time, adjust it to B's timezone, and then check the date - A's timezone remains irrelevant.

    So if access expires for those US folks then (1) take the current time, (2) adjust it to the account's timezone, and (3) check the adjusted date. Same if access expires at Wednesday at your midnight.
    But if you care about the time, like if access expires at my midnight, or at 11:59pm on that Wednesday, then you need to use times.
    Last edited by requinix; May 7th, 2018 at 04:59 AM.
  18. #10
  19. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2016
    Location
    Cheshire, UK
    Posts
    85
    Rep Power
    72
    If you store all datetimes as UTC, and the countdowns are to a UTC time then job done
  20. #11
  21. A Change of Season
    Devshed Loyal (3000 - 3499 posts)

    Join Date
    Mar 2004
    Location
    Next Door
    Posts
    3,477
    Rep Power
    221
    For broadcast launches, "offer ends midnight Jan 25TH Eastern time". This could be 5 pm in another location.

    For evergreen launches, offer's timer for everyone is based on launch owners timezone. So, midnight in LA could be 4 pm in Russia.

    Makes sense?
  22. #12
  23. Impoverished Moderator
    Devshed Supreme Being (6500+ posts)

    Join Date
    Mar 2007
    Location
    Washington, USA
    Posts
    16,750
    Rep Power
    9646
    In other words, can the user specify a time with that date? You say "midnight Jan 25" which implies the user said they wanted midnight, and it could very well have been another time, so the answer sounds like a yes.

    So you need DATETIMEs and we're back to the original problem of timezones - and the solution of storing them in UTC. So we're back to not having problems anymore... except for you having to change everything to DATETIMEs.

    And even if there are circumstances where the user only picks a date, the time would be effectively midnight so you would store that.
  24. #13
  25. A Change of Season
    Devshed Loyal (3000 - 3499 posts)

    Join Date
    Mar 2004
    Location
    Next Door
    Posts
    3,477
    Rep Power
    221
    This is the date picker where they select expiry date. Sorry, I shouldn't have said midnight.

    And this is how they specify when PLCs open.

    And this is how they set the launch sales page (after PLCs)

    Evergreen roadmap Or this one.

    No time. Everything is based on launch owners account. And all offers end on midnight.

    If we set the timezone to let's say Miami (Eastern), when someone from Turkey joins, they see the timer expire X days Miami time. That may be for example 4 pm Turkey.
    just like a true live launch, you would have the promotion ends at a specific time zone.
  26. #14
  27. Impoverished Moderator
    Devshed Supreme Being (6500+ posts)

    Join Date
    Mar 2007
    Location
    Washington, USA
    Posts
    16,750
    Rep Power
    9646
    Okay, then back to what I said before: take the current (or whenever) time, convert it to the owner's timezone, and check the date. You don't need times in the database, or to store timezones anywhere, or to convert them to or from the database. They only get involved at the moment when you need to compare a moment in time to a date.
  28. #15
  29. A Change of Season
    Devshed Loyal (3000 - 3499 posts)

    Join Date
    Mar 2004
    Location
    Next Door
    Posts
    3,477
    Rep Power
    221
    Hey;

    I got everything working well.

    Thanks for the help as usual, you've been incredibly helpful.


IMN logo majestic logo threadwatch logo seochat tools logo