Help with data Hook to replace time fields with a specific time.

Is it possible to add a before insert and before update hook to replace the default times in date fields with a specific time? If so can an if statement also be integrated to provide 2 time ranges based on a number or nights?


I already have hooks in place which automatically calculate the number of nights.

I now need to change the default times to;

If 5 nights or less the times would be 4pm to 4pm
If 6 nights or more the times would be 12noon to 12noon.

I have a feeling this will break quite a lot of existing code which is using the 12am to 12am to show data but I should be able to get around that hopefully.

Any help would be appreciated.

This is what I tested. The content manager shows a different time but the console.log shows the correct local times for me. When the item data is returned on the page, the time is correct- I believe the content manager time format is in UTC and for some reason, does not represent the local time. So although my code will show content manager times that are not 4 pm and noon, the item time values are actually 12 & 4 pm when running in the browsers console. But here’s my hook example.

function daysBetween ( end , start ) {
let difference = end . getTime () - start . getTime ();
let TotalDays = Math . ceil ( difference / ( 1000 * 3600 * 24 ));
return TotalDays ;
}

export function Library_beforeUpdate ( item , context ) {
if ( item ) {
//format start date
let sDate = new Date ( item . startDate )
let sYear = sDate . getFullYear ()
let sMonth = sDate . getMonth ()
let sDay = sDate . getDate ()
let formattedSDate = new Date ( sYear , sMonth , sDay )

    //format end date 
    **let**  eDate  =  **new**  Date ( item . endDate ) 
    **let**  eYear  =  eDate . getFullYear () 
    **let**  eMonth  =  eDate . getMonth () 
    **let**  eDay  =  eDate . getDate () 
    **let**  formattedEDate  =  **new**  Date ( eYear ,  eMonth ,  eDay ) 
    **let**  days 

    **if**  (! item . daysBetween ) { 
        days  =  daysBetween ( formattedEDate ,  formattedSDate ) 
        console . log ( 'days between' ,  days ) 
        //update item 
        item . daysBetween  =  days 
    } 

    //run this if days between exists or not 
    **if**  ( days  ||  item . daysBetween ) { 
        item . daysBetween  ?  days  =  item . daysBetween  :  **null** 

        **if**  ( days  <=  5 ) { 
            //4PM - 4PM 
            item . startDate  =  **new**  Date ( sYear ,  sMonth ,  sDay ,  16 )  //4 PM 
            console . log ( item . startDate ,  'start' ) 
            item . endDate  =  **new**  Date ( eYear ,  eMonth ,  eDay ,  16 )  //4 PM 
            console . log ( item . endDate ,  'start' ) 
        } 

        **if**  ( days  >=  6 ) { 
            //12PM - 12 PM 
            item . startDate  =  **new**  Date ( sYear ,  sMonth ,  sDay ,  12 )  //12 PM 
            console . log ( item . startDate ,  'start' ) 
            item . endDate  =  **new**  Date ( eYear ,  eMonth ,  eDay ,  12 )  //12 PM 
            console . log ( item . endDate ,  'start' ) 
        } 
    } 

    //return item  
    **return**  item 
} 

}

Apologies for the delay. Once again thank you very much for taking the time to post such a detailed response. You efforts are hugely appreciated.

I have manage to get this to work but I only needed to use and slighly modify the code below. As I already had the code for formatting the times. My only issue remaining is this only works for new data and won’t update my existing times. Is there a ways to force it to update?

            **if**  ( item . nights  <=  5 ) { 
            //4PM - 4PM 
            item . startDate  =  **new**  Date ( sYear ,  sMonth ,  sDay ,  16 )  //4 PM 
            console . log ( item . startDate ,  'start' ) 
            item . finishDate  =  **new**  Date ( eYear ,  eMonth ,  eDay ,  16 )  //4 PM 
            console . log ( item . finishDate ,  'start' ) 
        } 

        **if**  ( item . nights  >=  6 ) { 
            //12PM - 12 PM 
            item . startDate  =  **new**  Date ( sYear ,  sMonth ,  sDay ,  12 )  //12 PM 
            console . log ( item . startDate ,  'start' ) 
            item . finishDate  =  **new**  Date ( eYear ,  eMonth ,  eDay ,  12 )  //12 PM 
            console . log ( item . finishDate ,  'start' ) 
        } 



            **return**  item  

}

You can just create an export function in the backend and run it in order to return the new values. You can do it all from a single query based function as long as your limit/data does not exceed 1000.

I’m not sure how to do that, I’ve tried adding the code into a beforeQuery hook and even afterQuery in the data.js but that doesn’t seem to help.

No need to make it a hook, especially if you are running queries on your live site in the code panel.

You can build something like this in either a .js or .jsw file. I tried another example below and tried to keep the code similar to what you have. Use this to find days between any item in the database and add the value to the ‘daysBetween’ field key in the CM:

/* code is inside a JSW backend file /*

import wixData from ‘wix-data’ ;

export async function getDataQuery ( ) {
let data = await wixData . query ( ‘test’ ). limit ( 1000 ). find ()
return data . items
}

export async function updateMissingDaysBetween ( ) {
let data = await getDataQuery ()
data . forEach (( item ) => {
console . log ( ‘item’ , item . _id , item . daysBetween )

    //format start date 
    **let**  sDate  =  **new**  Date ( item . startDate ) 
    **let**  sYear  =  sDate . getFullYear () 
    **let**  sMonth  =  sDate . getMonth () 
    **let**  sDay  =  sDate . getDate () 
    **let**  formattedSDate  =  **new**  Date ( sYear ,  sMonth ,  sDay ) 

    //format end date 
    **let**  eDate  =  **new**  Date ( item . endDate ) 
    **let**  eYear  =  eDate . getFullYear () 
    **let**  eMonth  =  eDate . getMonth () 
    **let**  eDay  =  eDate . getDate () 
    **let**  formattedEDate  =  **new**  Date ( eYear ,  eMonth ,  eDay ) 
    **let**  days 

    **if**  (! item . daysBetween ) { 
        days  =  daysBetween ( formattedEDate ,  formattedSDate ) 
        console . log ( 'days between' ,  days ) 
        //update item 
        item . daysBetween  =  days 
        singleUpdate ( item ) 
        **return**  item 
    } 
}) 

}

function daysBetween ( end , start ) {
let difference = end . getTime () - start . getTime ();
let TotalDays = Math . ceil ( difference / ( 1000 * 3600 * 24 ));
return TotalDays ;
}

function singleUpdate ( toUpdate ) {
wixData . update ( “test” , toUpdate )
. then (( results ) => {
console . log ( results ); //see item below
})
. catch (( err ) => {
console . log ( err );
});
}

Once all the fields have the ‘daysBetween’ field calculated, you can update the times. Note that the times illustrated in the database are based on servers, not local so it is not an exact time in the database, but when you use a time string on your live site, it should = your local time. Example here:

export async function updateTimes ( ) {
//can use either bulk upate or single update here – showing the bulk update example here.
let items = {
lessThan5 : [],
moreThan5 : []
}

**let**  data  =  **await**  getDataQuery () 
**let**  less  =  data . filter (( item ) =>  item . daysBetween  <=  5 )  //4PM 
**let**  more  =  data . filter (( item ) =>  item . daysBetween  >=  6 )  //12 PM 

**if**  ( less ) { 
    less . forEach (( item ) => { 
        **let**  sDate  =  **new**  Date ( item . startDate ) 
        **let**  sYear  =  sDate . getFullYear () 
        **let**  sMonth  =  sDate . getMonth () 
        **let**  sDay  =  sDate . getDate () 
        **let**  formattedSDate  =  **new**  Date ( sYear ,  sMonth ,  sDay ) 

        //format end date 
        **let**  eDate  =  **new**  Date ( item . endDate ) 
        **let**  eYear  =  eDate . getFullYear () 
        **let**  eMonth  =  eDate . getMonth () 
        **let**  eDay  =  eDate . getDate () 
        **let**  formattedEDate  =  **new**  Date ( eYear ,  eMonth ,  eDay ) 
        **let**  days 

        //4PM - 4PM 
        item . startDate  =  **new**  Date ( sYear ,  sMonth ,  sDay ,  16 )  //4 PM 
        console . log ( item . startDate ,  'start' ) 
        item . endDate  =  **new**  Date ( eYear ,  eMonth ,  eDay ,  16 )  //4 PM 
        console . log ( item . endDate ,  'end' ) 

        //push into my new obj to bulk update 
        items . lessThan5 . push ( item ) 
    }) 

} 
**if**  ( more ) { 
    more . forEach (( item ) => { 
        **let**  sDate  =  **new**  Date ( item . startDate ) 
        **let**  sYear  =  sDate . getFullYear () 
        **let**  sMonth  =  sDate . getMonth () 
        **let**  sDay  =  sDate . getDate () 
        **let**  formattedSDate  =  **new**  Date ( sYear ,  sMonth ,  sDay ) 

        //format end date 
        **let**  eDate  =  **new**  Date ( item . endDate ) 
        **let**  eYear  =  eDate . getFullYear () 
        **let**  eMonth  =  eDate . getMonth () 
        **let**  eDay  =  eDate . getDate () 
        **let**  formattedEDate  =  **new**  Date ( eYear ,  eMonth ,  eDay ) 
        **let**  days 

        //12PM - 12PM 
        item . startDate  =  **new**  Date ( sYear ,  sMonth ,  sDay ,  12 )  //12 PM 
        console . log ( item . startDate ,  'start' ) 
        item . endDate  =  **new**  Date ( eYear ,  eMonth ,  eDay ,  12 )  //12 PM 
        console . log ( item . endDate ,  'end' ) 

        //push into my new obj to bulk update 
        items . moreThan5 . push ( item ) 
    }) 
} 

//time to bulk update 
items . lessThan5 . length  >  0  ?  bulkUpdate ( items . lessThan5 ) :  **null** 
items . moreThan5 . length  >  0  ?  bulkUpdate ( items . moreThan5 ) :  **null** 

}

function bulkUpdate ( toUpdate ) {
wixData . bulkUpdate ( “test” , toUpdate )
. then (( results ) => {
let inserted = results . inserted ; // 0
let insertedIds = results . insertedItemIds ; // []
let updated = results . updated ; // 2
let skipped = results . skipped ; // 0
let errors = results . errors ; // []
console . log ( updated , ‘= updated’ , errors , ‘= errors’ )
})
. catch (( err ) => {
console . log ( err , ‘error message’ )
});
}