Here is another fun way of doing it which is a lot faster and cheaper to do:
If you run a SPV client like Electrum on your computer you already have all the block headers saved up in a ~60 MB file called "blockchain_headers" which is a stream of bytes. All you have to do is to programatically read this file to get the raw bytes which should be a multiple of 80. Each 80 byte is a block header of a block in chronological order (so you have the block height this way too). Then start from the beginning (byte 0) and extract the time from each 80 byte chunk (ie. one header) knowing that 4th item in it is the timestamp.
version[4] + prev_hash[32] + merkle_root[32] + time[4] + target[4] + nonce[4]
Here is a pseudocode
stream = File.Read("blockchain_headers")
while(stream.HasBytesLeft)
stream.Skip(68)
timestamp = stream.Read(4).ConvertToTime_LittleEndian()
resultList.Add(timestamp)
stream.Skip(8)
Now all you have to do is search in the list of timestamps to see when the day in the datetime you converted changes to get the last height of the day. The height is the index of the datetime inside the resultList/array.
Keep in mind that timestamps are in UTC not your local time.