Essentially, this is a repost of this question: https://confluence.ecmwf.int/pages/viewpage.action?pageId=149341027
I have downloaded ERA5 from the CDS. The input fi
# Correction to above python example to account for the time shift, as in the CDO example. Input file always needs to have the following day to the last day for which you want to compute daily sums/averages
import xarray as xr
ds_nc = xr.open_dataset('name_of_your_file.nc') # read the file
sds= ds_nc.shift(time=-1).dropna(dim='time',how='all') # shift to account for time shift for accumulated variables
daily_precipitation = sds.tp.resample(time='24H').sum('time')*1000 # calculate sum with frequency of 24h and multiply by 1000
# need to figure start_time and end_time for separately or slice differently.
sdaily=daily_precipitation.sel(time=slice("<start_time>", "<end_time>)") # drop the last value because values aren't complete.
sdaily.to_netcdf('daily_prec.nc')
For these kind of issues, the useful command in CDO is shifttime, which essentially does what is says on the can and shifts the time stamp.
This kind of problem arises frequently with any kind of flux or accumulated field where the timestamp allocated to the data value points to the END of the time accumulation period, or "window", for example, with 3 hourly TRMM data the last three hours of the day have the stamp of 00 on the date afterwards, and functions such as daymean or daysum applied directly will calculate the average of 21 hours in one day and 3 hours from the previous day, incorrectly. Shifting the timestamp by three hours so the time points to the start of the window (or indeed by 1.5, pointing to the middle) before you perform the calculation will resolve this.
So for your specific question where you have a long series of hourly data from ERA5 and you want the daily total, you can do:
cdo shifttime,-1hour in.nc shift.nc # now step 0 on Jan 2 has Jan 1, 23:00 stamp
cdo daysum shift.nc daysum.nc
or piped together:
cdo daysum -shifttime,-1hour in.nc daysum.nc
(NOTE: This procedure is not the same to users of fluxes from the older ERA-Interim, where the fluxes are accumulated through the short forecast period. For ERA5 the "deaccumulation" is already done for you. With ERA-Interim you need to difference consecutive timesteps to convert from an accumulated field, and there is a post here that shows how to do this with CDO or python: Better dispersion of accumulated netcdf timesteps with CDO )